熊猫-团结完成专栏

时间:2018-08-21 08:19:25

标签: 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  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 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

如果性能很重要,请使用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的预期输出都在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

答案 2 :(得分:1)

尝试:

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

答案 3 :(得分:1)

仅出于多样性的考虑-您还可以使用NETWORK_NAME=my_local_network if [ -z $(docker network ls --filter name=^${NETWORK_NAME}$ --format="{{ .Name }}") ] ; then docker network create ${NETWORK_NAME} ; fi

df.lookup()

但是,这不是最快的解决方案,因为afaik @jezrael发布了最快的解决方案:

10000次重复的timeit结果:

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