2017-08-31 57 views
2

我需要連接熊貓數據框的2列或更多列中的字符串。將缺失值的熊貓字符串列組合起來

我發現這個answer,它工作正常,如果你沒有任何缺失值。不幸的是,我有,而這導致像「ValueA; None」這樣的事情,這不是很乾淨。

示例數據:

col_A | col_B 
------ | ------ 
val_A | val_B 
None | val_B 
val_A | None 
None | None 

我需要這樣的結果:

col_merge 
--------- 
val_A;val_B 
val_B 
val_A 
None 
+2

你嘗試使用fillna與col_b一個空字符串 ''? – Quickbeam2k1

+0

剛剛做過,但如果我在第一列中有NaN,我會得到「; val_B」。在這兩欄中我都會看到「;」 – CoMartel

回答

5

您可以使用applyif-else

df = df.apply(lambda x: None if x.isnull().all() else ';'.join(x.dropna()), axis=1) 
print (df) 
0 val_A;val_B 
1   val_B 
2   val_A 
3   None 
dtype: object 

爲了更快的解決方案是可能的用途:

#add separator and replace NaN to empty space 
#convert to lists 
arr = df.add('; ').fillna('').values.tolist() 
#list comprehension, replace empty spaces to NaN 
s = pd.Series([''.join(x).strip('; ') for x in arr]).replace('^$', np.nan, regex=True) 
#replace NaN to None 
s = s.where(s.notnull(), None) 
print (s) 
0 val_A;val_B 
1   val_B 
2   val_A 
3   None 
dtype: object 

#40000 rows 
df = pd.concat([df]*10000).reset_index(drop=True) 

In [70]: %%timeit 
    ...: arr = df.add('; ').fillna('').values.tolist() 
    ...: s = pd.Series([''.join(x).strip('; ') for x in arr]).replace('^$', np.nan, regex=True) 
    ...: s.where(s.notnull(), None) 
    ...: 
10 loops, best of 3: 74 ms per loop 


In [71]: %%timeit 
    ...: df.apply(lambda x: None if x.isnull().all() else ';'.join(x.dropna()), axis=1) 
    ...: 
1 loop, best of 3: 12.7 s per loop 

#another solution, but slowier a bit 
In [72]: %%timeit 
    ...: arr = df.add('; ').fillna('').values 
    ...: s = [''.join(x).strip('; ') for x in arr] 
    ...: pd.Series([y if y != '' else None for y in s]) 
    ...: 
    ...: 
10 loops, best of 3: 119 ms per loop 
+0

工作正常,謝謝! – CoMartel

+0

很高興能幫到你,祝你好運! – jezrael