我有一个Pandas DataFrame,如下所示:
col1 col2 col3
1 0.2 0.3 0.3
2 0.2 0.3 0.3
3 0 0.4 0.4
4 0 0 0.3
5 0 0 0
6 0.1 0.4 0.4
我想将col1
值替换为第二列(col2
)中的值,仅当col1
值等于0且之后(对于剩余的零值) ,再做一次,但使用第三列(col3
)。期望的结果是下一个:
col1 col2 col3
1 0.2 0.3 0.3
2 0.2 0.3 0.3
3 0.4 0.4 0.4
4 0.3 0 0.3
5 0 0 0
6 0.1 0.4 0.4
我是使用pd.replace
函数完成的,但它似乎太慢了......我认为必须以更快的方式完成它。
df.col1.replace(0,df.col2,inplace=True)
df.col1.replace(0,df.col3,inplace=True)
有更快的方法吗?使用其他函数而不是pd.replace
函数?
答案 0 :(得分:15)
使用np.where
的速度更快。使用与replace
:
df['col1'] = np.where(df['col1'] == 0, df['col2'], df['col1'])
df['col1'] = np.where(df['col1'] == 0, df['col3'], df['col1'])
但是,使用嵌套的np.where
稍快一些:
df['col1'] = np.where(df['col1'] == 0,
np.where(df['col2'] == 0, df['col3'], df['col2']),
df['col1'])
<强>计时强>
使用以下设置生成更大的样本DataFrame和计时功能:
df = pd.concat([df]*10**4, ignore_index=True)
def root_nested(df):
df['col1'] = np.where(df['col1'] == 0, np.where(df['col2'] == 0, df['col3'], df['col2']), df['col1'])
return df
def root_split(df):
df['col1'] = np.where(df['col1'] == 0, df['col2'], df['col1'])
df['col1'] = np.where(df['col1'] == 0, df['col3'], df['col1'])
return df
def pir2(df):
df['col1'] = df.where(df.ne(0), np.nan).bfill(axis=1).col1.fillna(0)
return df
def pir2_2(df):
slc = (df.values != 0).argmax(axis=1)
return df.values[np.arange(slc.shape[0]), slc]
def andrew(df):
df.col1[df.col1 == 0] = df.col2
df.col1[df.col1 == 0] = df.col3
return df
def pablo(df):
df['col1'] = df['col1'].replace(0,df['col2'])
df['col1'] = df['col1'].replace(0,df['col3'])
return df
我得到以下时间:
%timeit root_nested(df.copy())
100 loops, best of 3: 2.25 ms per loop
%timeit root_split(df.copy())
100 loops, best of 3: 2.62 ms per loop
%timeit pir2(df.copy())
100 loops, best of 3: 6.25 ms per loop
%timeit pir2_2(df.copy())
1 loop, best of 3: 2.4 ms per loop
%timeit andrew(df.copy())
100 loops, best of 3: 8.55 ms per loop
我试过计时你的方法,但它已经运行了几分钟而没有完成。作为比较,仅在6行示例中对您的方法进行计时DataFrame(不是上面测试的大得多)花了12.8 ms。
答案 1 :(得分:5)
我不确定它是否更快,但您可以将数据帧切片以获得所需的结果。
df.col1[df.col1 == 0] = df.col2
df.col1[df.col1 == 0] = df.col3
print(df)
输出:
col1 col2 col3
0 0.2 0.3 0.3
1 0.2 0.3 0.3
2 0.4 0.4 0.4
3 0.3 0.0 0.3
4 0.0 0.0 0.0
5 0.1 0.4 0.4
或者,如果你想要它更简洁(虽然我不知道它是否更快),你可以把你做的和我做的结合起来。
df.col1[df.col1 == 0] = df.col2.replace(0, df.col3)
print(df)
输出:
col1 col2 col3
0 0.2 0.3 0.3
1 0.2 0.3 0.3
2 0.4 0.4 0.4
3 0.3 0.0 0.3
4 0.0 0.0 0.0
5 0.1 0.4 0.4
答案 2 :(得分:2)