Pandas - 合并补全列

3
假设我有以下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  str3
5     0  str4
6     0  str5

其中r1是“完成”r2(当一个是0时,另一个是string),反之亦然。

最快的方法是将它们合并并获得以下DataFrame:

    r_u
0  str1
1  str2
2  str1
3  str2
4  str3
5  str4
6  str5
4个回答

2

如果性能很重要,请使用numpy.select

#more general solution 
df = pd.DataFrame({'r1' : [0, 0, 'str1', 'str2', 0 ,0 ,0, 0, 'str7'], 
                   'r2' : ['str1', 'str2', 0, 0, 'str3', 'str4', 'str5', 0, 'str8']})
print (df)
     r1    r2
0     0  str1
1     0  str2
2  str1     0
3  str2     0
4     0  str3
5     0  str4
6     0  str5
7     0     0 
8  str7  str8

如果在默认参数中定义了期望输出的0,并且两个字符串都有可能,那么按照掩码和列的顺序优先考虑它们。
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

1
使用 pd.Series.maskpd.Series.ffill,然后使用 iloc 访问器:
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.87秒。虽然如此,回答很好。Jezrael 花费了 0.10 秒。 - Eran Moshe
@EranMoshe,当然可以。我的意思是,如果这真的是您的瓶颈,请尽管选择更快的答案。如果这些也是问题,考虑可维护性/可扩展性也很重要。 - jpp
你说得没错,但这只是一个“补丁”,大约会持续30-60天,然后就会被移除。 - Eran Moshe

1

尝试:

df['r3']=(df['r1'].astype(str) + df['r2'].astype(str)).str.replace('0', '')

1

为了多样化考虑,您也可以使用df.lookup()

df['r3'] = df.lookup(df.index, [['r1', 'r2'][int(v==0)] for v in df.r1])

然而,这不是最快的解决方案,据我所知@jezrael发布了最快的解决方案:
10000次重复的timeit结果:
lookup
3.846349009425694

mask
18.704440796350127

np.select
2.7935229356389755

str.replace
6.296438898734323

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接