Python 熊猫-联合完成列
假设我有以下DataFrame对象:Python 熊猫-联合完成列,python,pandas,series,Python,Pandas,Series,假设我有以下DataFrame对象: import pandas as pd df = pd.DataFrame({'r1' : [0, 0, 'str1', 'str2', 0 ,0 ,0], 'r2' : ['str1', 'str2', 0, 0, 'str3', 'str4', 'str5']}) df Out[45]: r1 r2 0 0 str1 1 0 str2 2 str1 0 3 str2 0 4 0 str
import pandas as pd
df = pd.DataFrame({'r1' : [0, 0, 'str1', 'str2', 0 ,0 ,0], 'r2' : ['str1', 'str2', 0, 0, 'str3', 'str4', 'str5']})
df
Out[45]:
r1 r2
0 0 str1
1 0 str2
2 str1 0
3 str2 0
4 0 str3
5 0 str4
6 0 str5
其中,r1
是“完成”r2
(当一个是0
时,另一个是字符串
),反之亦然
将两者结合起来并获得以下数据帧的最快方法是什么:
r_u
0 str1
1 str2
2 str1
3 str2
4 str3
5 str4
6 str5
使用and,后跟访问器:
df['r3'] = df.mask(df.eq(0)).ffill(1).iloc[:, -1]
print(df)
r1 r2 r3
0 0 str1 str1
1 0 str2 str2
2 str1 0 str1
3 str2 0 str2
4 0 str3 str3
5 0 str4 str4
6 0 str5 str5
为了获得较小的额外加速,您可以使用NumPy数组进行比较,即将
df.eq(0)
替换为df.values==0
,如果性能很重要,请使用:
如果两个0
预期输出都在default
参数中定义,并且如果两个参数中的字符串都可以,则按掩码和列的顺序对它们进行优先级排序:
m1 = df['r1'] != 0
m2 = df['r2'] != 0
df['r3'] = np.select([m1, m2], [df['r1'], df['r2']], default=None)
df['r4'] = np.select([m2, m1], [df['r2'], df['r1']], default=None)
print (df)
r1 r2 r3 r4
0 0 str1 str1 str1
1 0 str2 str2 str2
2 str1 0 str1 str1
3 str2 0 str2 str2
4 0 str3 str3 str3
5 0 str4 str4 str4
6 0 str5 str5 str5
7 0 0 None None
8 str7 str8 str7 str8
尝试:
为了多样性,您还可以使用
df.lookup()
:
然而,这并不是最快的解决方案,因为afaik@jezrael发布了最快的解决方案:
10000次重复的timeit结果:
lookup
3.846349009425694
mask
18.704440796350127
np.select
2.7935229356389755
str.replace
6.296438898734323
得分:0.87。回答得不错。耶斯雷尔拿了0分。10s@EranMoshe当然我的意思是,如果这真的是你的瓶颈,那么一定要选择更快的答案。如果这些也是值得考虑的问题,那么也值得考虑可维护性/可扩展性。您是正确的,但这是一个“补丁”,将持续30-60天,并将被删除。这里有一个假设,即您的真实字符串不包括
'0'
@jpp
df['r3']=(df['r1'].astype(str) + df['r2'].astype(str)).str.replace('0', '')
df['r3'] = df.lookup(df.index, [['r1', 'r2'][int(v==0)] for v in df.r1])
lookup
3.846349009425694
mask
18.704440796350127
np.select
2.7935229356389755
str.replace
6.296438898734323