我有一个有四列的大型df.其中一列包含单词,另一列将这些单词作为词典的关键字.我需要添加另一个专栏,提取感兴趣单词的值.示例:

ID        ID2     words      dict1
x12_12    12984   apple      {'apple': 5, 'pear': 10}
x12_12    12984   pear       {'apple': 5, 'pear': 10}
x12_12    20934   orange     {'orange': 5, 'pear': NaN}
x12_12    20934   pear       {'orange': 5, 'pear': NaN}

我需要创建一个名为Value的新列来从DICE1中提取信息

ID        ID2     words      dict1                         value
x12_12    12984   apple      {'apple': 5, 'pear': 10}      5
x12_12    12984   pear       {'apple': 5, 'pear': 10}      10
x12_12    20934   orange     {'orange': 20, 'pear': NaN}   20
x12_12    20934   pear       {'orange': 20, 'pear': NaN}   NaN

我有这个代码,它给了我想要的结果,但它需要很长时间才能运行,而且我有一个非常大的数据集.我知道‘应用’对于 Big Data 来说并不是最有效的.

df['value'] = df.apply(lambda row: row['dict1'][row['words']], axis=1)

有没有更快的方法?我try 使用np.vectorize,但它有一个问题与nan值,我不断得到错误.

推荐答案

最简单的 Select :使用zip的列表理解:

df['value'] = [d.get(w) for w,d in zip(df['words'], df['dict1'])]

或者,将json_normalizeindexing lookup合并:

idx, cols = pd.factorize(df['words'])

df['value'] = (pd.json_normalize(df['dict1'])
                 .reindex(cols, axis=1).to_numpy()
               [np.arange(len(df)), idx]
              )

或使用groupby.transform:

df['value'] = (df.groupby('words', as_index=False)['dict1']
                 .apply(lambda g: g.str[g.name]).droplevel(0)
              )

输出:

       ID    ID2   words                       dict1  value
0  x12_12  12984   apple    {'apple': 5, 'pear': 10}    5.0
1  x12_12  12984    pear    {'apple': 5, 'pear': 10}   10.0
2  x12_12  20934  orange  {'orange': 5, 'pear': nan}    5.0
3  x12_12  20934    pear  {'orange': 5, 'pear': nan}    NaN
Timings

在400k行.最后,列表理解是最快的,这是有意义的,因为限制步骤无论如何都是基于循环的.apply是一个循环,但由于为每行创建一个Series,因此开销很大.如果可以的话,一定要用列表理解来代替axis=1中的apply.

# apply
2.58 s ± 33.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# list comprehension
127 ms ± 7.65 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

# json_normalize + indexing lookup
811 ms ± 46 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# groupby.transform
237 ms ± 3.22 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Python相关问答推荐

如何在图片中找到这个化学测试条?OpenCV精明边缘检测不会绘制边界框

将DF中的名称与另一DF拆分并匹配并返回匹配的公司

Pandas 在最近的日期合并,考虑到破产

Python json.转储包含一些UTF-8字符的二元组,要么失败,要么转换它们.我希望编码字符按原样保留

pyscript中的压痕问题

用渐近模计算含符号的矩阵乘法

无论输入分辨率如何,稳定扩散管道始终输出512 * 512张图像

如何更改groupby作用域以找到满足掩码条件的第一个值?

如何使regex代码只适用于空的目标单元格

手动设置seborn/matplotlib散点图连续变量图例中显示的值

numpy.unique如何消除重复列?

python sklearn ValueError:使用序列设置数组元素

Numpyro AR(1)均值切换模型抽样不一致性

在Python中从嵌套的for循环中获取插值

如何使用matplotlib查看并列直方图

多个矩阵的张量积

如何防止html代码出现在quarto gfm报告中的pandas表之上

如何在Pandas中用迭代器求一个序列的平均值?

在Pandas 中以十六进制显示/打印列?

Pandas:使列中的列表大小与另一列中的列表大小相同