pandas 将字符串加入一个组,跳过 na 值
pandas joining strings in a group, skipping na values
为了按行汇总数据。
col_str
,可能包含 nan
个值。不出所料,如 str.join
documentation 所示,加入 nan 将导致空字符串:
df = df.join(df['col_a'].map(df.groupby('col_a')['col_str'].unique().str.join(', '))
为了缓解这种情况,我尝试将 col_str
转换为字符串(例如 df['col_str'] = df['col_str'].astype(str)
)。但是,空值现在确实有一个字符串 nan
值,因此被认为是非空的。
不仅 str.join
现在包括 nan
字符串,而且依赖于这些 nan 的脚本上的其他计算也被破坏了。
为了解决这个问题,我考虑过如下仅转换非空值:
df['col_str'] = np.where(pd.isnull(df['col_str']), df['col_str'],
df['col_str'].astype(str))
但是现在 str.join
return 又是空值:-(
所以,我尝试了 fillna('')
,甚至 dropna()
。 None 为我提供了想要的结果。
你明白了这里的恶性循环,对吧?
astype(str)
=> nan
连接和计算中的字符串已损坏
保持原样 => join.str
returns 空结果。
感谢您的协助!
编辑:
从 csv 中读取数据。样本:
要测试的代码 -
df = pd.read_csv('/Users/goidelg/Downloads/sample_data.csv', low_memory=False)
print("---Original DF ---")
print(df)
print("---Joining NaNs as NaN---")
print(df.join(df['col_a'].map(df.groupby('col_a')['col_str'].unique().str.join(', ')).rename('strings_concat')))
print("---Convertin col to str---")
df['col_str'] = df['col_str'].astype(str)
print(df.join(df['col_a'].map(df.groupby('col_a')['col_str'].unique().str.join(', ')).rename('strings_concat')))
以及脚本的结果:
首先删除缺失值 DataFrame.dropna
or Series.notna
in boolean indexing
:
df = pd.DataFrame({'col_a':[1,2,3,4,1,2,3,4,1,2],
'col_str':['a','b','c','d',np.nan, np.nan, np.nan, np.nan,'a', 's']})
df1 = (df.join(df['col_a'].map(df[df['col_str'].notna()]
.groupby('col_a')['col_str'].unique()
.str.join(', ')). rename('labels')))
print (df1)
col_a col_str labels
0 1 a a
1 2 b b, s
2 3 c c
3 4 d d
4 1 NaN a
5 2 NaN b, s
6 3 NaN c
7 4 NaN d
8 1 a a
9 2 s b, s
df2 = (df.join(df['col_a'].map(df.dropna(subset=['col_str'])
.groupby('col_a')['col_str']
.unique().str.join(', ')).rename('labels')))
print (df2)
col_a col_str labels
0 1 a a
1 2 b b, s
2 3 c c
3 4 d d
4 1 NaN a
5 2 NaN b, s
6 3 NaN c
7 4 NaN d
8 1 a a
9 2 s b, s
为了按行汇总数据。
col_str
,可能包含 nan
个值。不出所料,如 str.join
documentation 所示,加入 nan 将导致空字符串:
df = df.join(df['col_a'].map(df.groupby('col_a')['col_str'].unique().str.join(', '))
为了缓解这种情况,我尝试将 col_str
转换为字符串(例如 df['col_str'] = df['col_str'].astype(str)
)。但是,空值现在确实有一个字符串 nan
值,因此被认为是非空的。
不仅 str.join
现在包括 nan
字符串,而且依赖于这些 nan 的脚本上的其他计算也被破坏了。
为了解决这个问题,我考虑过如下仅转换非空值:
df['col_str'] = np.where(pd.isnull(df['col_str']), df['col_str'],
df['col_str'].astype(str))
但是现在 str.join
return 又是空值:-(
所以,我尝试了 fillna('')
,甚至 dropna()
。 None 为我提供了想要的结果。
你明白了这里的恶性循环,对吧?
astype(str)
=> nan
连接和计算中的字符串已损坏
保持原样 => join.str
returns 空结果。
感谢您的协助!
编辑:
从 csv 中读取数据。样本:
要测试的代码 -
df = pd.read_csv('/Users/goidelg/Downloads/sample_data.csv', low_memory=False)
print("---Original DF ---")
print(df)
print("---Joining NaNs as NaN---")
print(df.join(df['col_a'].map(df.groupby('col_a')['col_str'].unique().str.join(', ')).rename('strings_concat')))
print("---Convertin col to str---")
df['col_str'] = df['col_str'].astype(str)
print(df.join(df['col_a'].map(df.groupby('col_a')['col_str'].unique().str.join(', ')).rename('strings_concat')))
以及脚本的结果:
首先删除缺失值 DataFrame.dropna
or Series.notna
in boolean indexing
:
df = pd.DataFrame({'col_a':[1,2,3,4,1,2,3,4,1,2],
'col_str':['a','b','c','d',np.nan, np.nan, np.nan, np.nan,'a', 's']})
df1 = (df.join(df['col_a'].map(df[df['col_str'].notna()]
.groupby('col_a')['col_str'].unique()
.str.join(', ')). rename('labels')))
print (df1)
col_a col_str labels
0 1 a a
1 2 b b, s
2 3 c c
3 4 d d
4 1 NaN a
5 2 NaN b, s
6 3 NaN c
7 4 NaN d
8 1 a a
9 2 s b, s
df2 = (df.join(df['col_a'].map(df.dropna(subset=['col_str'])
.groupby('col_a')['col_str']
.unique().str.join(', ')).rename('labels')))
print (df2)
col_a col_str labels
0 1 a a
1 2 b b, s
2 3 c c
3 4 d d
4 1 NaN a
5 2 NaN b, s
6 3 NaN c
7 4 NaN d
8 1 a a
9 2 s b, s