【问题标题】:Cannot split pandas dataframe column due to NaN values由于 NaN 值,无法拆分 pandas 数据框列
【发布时间】:2021-07-29 08:39:43
【问题描述】:

我们有以下凌乱的数据框:

print(df[7:9].to_dict())
{'Scheduled': {7: 'END 3RD: 0-0, 3 Out917YankeesNYY918RaysTB', 8: 'TOP 3RD: 1-2, 2 Out915Blue JaysTOR916Red SoxBOS'}, 'Open': {7: '+115-135', 8: '-115-105'}, 'Best Odds': {7: '+125ML+130ML', 8: '+120ML-125ML'}, '% of Bets': {7: '55%45%', 8: '31%69%'}, '% of Money': {7: '34%66%', 8: nan}, 'Diff': {7: '+21%', 8: nan}, 'Bets': {7: 12445, 8: 6178}}

df[7:9]
Scheduled   Open    Best Odds   % of Bets   % of Money  Diff    Bets
7   END 3RD: 0-0, 3 Out917YankeesNYY918RaysTB   +115-135    +125ML+130ML    55%45%  34%66%  +21%    12445
8   TOP 3RD: 1-2, 2 Out915Blue JaysTOR916Red SoxBOS -115-105    +120ML-125ML    31%69%  NaN NaN 6178

df.dtypes
Scheduled     object
Open          object
Best Odds     object
% of Bets     object
% of Money    object
Diff          object
Bets           int64
dtype: object

编辑:我尝试将print(df[7:9].to_dict()) 的输出粘贴到笔记本单元格中以运行代码,并收到错误NameError: name 'nan' is not defined。不确定如何分享可重现的示例?

我们正在遍历df,试图将其中一些列拆分为 2 列,因为每列包含 2 个团队的数据。 NaN 值导致问题,我们不能使用 math.isnan() 因为% of Money 是一列字符串,math.isnan() 似乎返回字符串错误。以下代码对我们不利:

for i, row in df.iterrows():
    string = row['% of Money']
    if len(string) == 2:
        num_pair_perc_mon = [string[0], string[1]]
    else:
        split_index = min([i for i, char in enumerate(string) if char in ['%']])
        num_pair_perc_mon = [string[:split_index + 1], string[split_index + 1:]]
    
    print(num_pair_perc_mon)
    df.at[i, 't1_pct_money'] = num_pair_perc_mon[0]
    df.at[i, 't2_pct_money'] = num_pair_perc_mon[1]

带输出:

我们如何成功地将% of Money 拆分为 2 列,处理我们在数据框中提供的 NaN?

【问题讨论】:

  • nan 完全没问题。 from numpy import nan 将使它不是未定义的。
  • min([i for i, char in enumerate(string) if char in ['%']]) 是一个问题,因为min 无法处理空集合。当单元格中没有任何东西时,您希望如何处理这个问题?

标签: python pandas dataframe


【解决方案1】:

我们可以尝试使用str.extractall 来提取与模式匹配的所有值。然后unstack 将捕获组从行转换为列:

import pandas as pd
from numpy import nan

df = pd.DataFrame({
    '% of Money': {7: '34%66%', 8: nan}
})

df[['t1_pct_money', 't2_pct_money']] = (
    df['% of Money'].str.extractall(r'([+-]?\d+%)').unstack()
)

df:

  % of Money t1_pct_money t2_pct_money
7     34%66%          34%          66%
8        NaN          NaN          NaN

正则表达式详细信息:

[+-]?\d+%
  • 匹配列表中存在的单个字符 [+-]
    • ? 匹配前一个令牌 0 到 1 次,尽可能多地匹配,根据需要回馈(贪婪)
    • +- 匹配列表中的单个字符 +-(区分大小写)
  • \d 匹配一个数字(相当于 [0-9])
    • + 匹配前一个令牌一次到无限次,尽可能多次,根据需要回馈(贪婪)
  • % 匹配字符 % 字面意思(区分大小写)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-13
    • 2019-07-25
    • 1970-01-01
    • 2018-11-02
    • 2015-01-15
    相关资源
    最近更新 更多