【发布时间】:2020-04-25 07:43:34
【问题描述】:
假设我有一个如下所示的数据框:
import pandas as pd
import numpy as np
np.random.seed(42)
df = pd.DataFrame({'A':np.random.randn(5), 'B': np.zeros(5), 'C': np.zeros(5)})
df
>>>
A B C
0 0.496714 0.0 0.0
1 -0.138264 0.0 0.0
2 0.647689 0.0 0.0
3 1.523030 0.0 0.0
4 -0.234153 0.0 0.0
当A 为负数时,我想用值 1 填充列的列表。
idx = df.A < 0
cols = ['B', 'C']
所以在这种情况下,我希望索引 [1, 'B'] 和 [4, 'C'] 设置为 1。
我尝试了什么:
但是,执行df.loc[idx, cols] = 1 会将整行设置为 1,而不仅仅是单个列。我也尝试过df.loc[idx, cols] = pd.get_dummies(cols),结果如下:
A B C
0 0.496714 0.0 0.0
1 -0.138264 0.0 1.0
2 0.647689 0.0 0.0
3 1.523030 0.0 0.0
4 -0.234153 NaN NaN
我假设这是因为get_dummies 的索引和数据框没有对齐。
预期输出:
A B C
0 0.496714 0.0 0.0
1 -0.138264 1.0 0.0
2 0.647689 0.0 0.0
3 1.523030 0.0 0.0
4 -0.234153 0.0 1.0
那么什么是最好的(阅读最快的)方法来做到这一点。在我的例子中,有 1000 行和 5 列。
结果时间:
TLDR:直接编辑值更快。
%%timeit
df.values[idx, df.columns.get_indexer(cols)] = 1
每个循环 123 µs ± 2.5 µs(7 次运行的平均值 ± 标准偏差,每次 10000 个循环)
%%timeit
df.iloc[idx.array,df.columns.get_indexer(cols)]=1
每个循环 266 µs ± 7 µs(7 次运行的平均值 ± 标准偏差,每次 1000 个循环)
【问题讨论】:
-
df.iloc[idx.array,df.columns.get_indexer(cols)]=1可能会成功