Python pandas 使用 fillna() 来避免对 NaN 值进行错误拆分
Posted
技术标签:
【中文标题】Python pandas 使用 fillna() 来避免对 NaN 值进行错误拆分【英文标题】:Python pandas use fillna() to avoid error splitting on NaN value 【发布时间】:2022-01-23 22:26:34 【问题描述】:my_df = pd.DataFrame(data = 'col0': ['1%2%', '3%4%'], 'col1': [np.nan, np.nan], 'col2': ['+1-2', '+2-4'], 'col3': [np.nan, '+2-4'], 'col4': [np.nan, np.nan] )
my_df[['col0a', 'col0b']] = my_df['col0'].fillna('%').str.split('%', expand = True).iloc[:, 0:2]
my_df[['col1a', 'col1b']] = my_df['col1'].fillna('%').str.split('%', expand = True).iloc[:, 0:2]
my_df[['col2a', 'col2b']] = my_df['col2'].str.split('(?<=[\d]|K)(?=[+-])', expand=True)
my_df[['col3a', 'col3b']] = my_df['col3'].str.split('(?<=[\d]|K)(?=[+-])', expand=True)
my_df[['col4a', 'col4b']] = my_df['col4'].str.split('(?<=[\d]|K)(?=[+-])', expand=True)
my_df
这会在my_df[['col4a', 'col4b']]
行引发错误,因为整列都是NaN
值。对于col1
,没有抛出错误,因为我们用%
填充,然后拆分在%
上拆分,导致两列包含空字符串,这正是我们想要的。
我们可以在col4
中添加什么fillna()
使其不会引发错误? col4 的拆分比 col1 的拆分更复杂(寻找 +#-# 的模式)。我们已经尝试过fillna('+-')
,但这不起作用。一般来说,我们正在寻找一种解决方案,当col4
的值为NaN
时,为col4a
和col4b
输出空字符串。
编辑: 措辞不同,我需要一个用于 fillna 的字符串,当传递给 .split('(?<=[\d]|K)(?=[+-])', expand=True)
时,会产生 2 个空字符串,尽管也许我可以用 fillna(+9999-9999)
之类的东西替换,然后用空字符串替换 9999...
【问题讨论】:
问题不在于拆分返回NaN。问题是拆分没有发生,因为 NaN 存在,并且用空字符串替换 NaN 不起作用,因为拆分输出需要 2 列。 【参考方案1】:一个(可能)更好的解决方案是使用.str.extract
而不是.str.split
,这更适合您的目的:
my_df = pd.DataFrame(data = 'col0': ['1%2%', '3%4%'], 'col1': [np.nan, np.nan], 'col2': ['+1-2', '+2-4'], 'col3': [np.nan, '+2-4'], 'col4': [np.nan, np.nan] )
my_df = my_df.fillna('')
pat1 = r'(\d+%)(\d+%)'
pat2 = r'([+-](?:[\d]+|K))([+-](?:[\d]+|K))'
my_df[['col0a', 'col0b']] = my_df['col0'].str.extract(pat1)
my_df[['col1a', 'col1b']] = my_df['col1'].str.extract(pat1)
my_df[['col2a', 'col2b']] = my_df['col2'].str.extract(pat2)
my_df[['col3a', 'col3b']] = my_df['col3'].str.extract(pat2)
my_df[['col4a', 'col4b']] = my_df['col4'].str.extract(pat2)
my_df = my_df.fillna('')
输出:
>>> my_df
col0 col1 col2 col3 col4 col0a col0b col1a col1b col2a col2b col3a col3b col4a col4b
0 1%2% +1-2 1% 2% +1 -2
1 3%4% +2-4 +2-4 3% 4% +2 -4 +2 -4
【讨论】:
这很棒。我想我会在最后 5 行的每一行末尾添加fillna('')
,因为我更喜欢空字符串而不是 NaN
,但另一方面,这看起来真的很好
@Canovic 请立即查看答案。我已经按照你说的做了,只是更简洁一点;)
我猜这里有一个问题是col0a
、col0b
在输出中丢失了%
登录
容易补救。请立即检查答案@Canovic ;)【参考方案2】:
并不完美,但这个 2 行解决方案比我目前使用的使用 if: else: 块的 8 行解决方案要好。
my_df[['col4a', 'col4b']] = my_df['col4'].fillna('+999999-999999').str.split('(?<=[\d]|K)(?=[+-])', expand=True)
my_df[['col4a', 'col4b']] = my_df[['col4a', 'col4b']].replace('+999999', '').replace('-999999', '')
【讨论】:
以上是关于Python pandas 使用 fillna() 来避免对 NaN 值进行错误拆分的主要内容,如果未能解决你的问题,请参考以下文章
Python pandas 使用 fillna() 来避免对 NaN 值进行错误拆分