あなたはif-else
でapply
を使用することができます。
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
あなたはcol_bに空の文字列 '' でfillna使用してみましたか? – Quickbeam2k1
ただしましたが、最初の列にNaNがある場合は、「; val_B」を取得します。両方の列にナンと私はちょうど得る ";" – CoMartel