【问题标题】:Mark Empty values in Pandas DataFrame Multi-Row Header在 Pandas DataFrame 多行标题中标记空值
【发布时间】:2018-01-02 22:28:40
【问题描述】:

我有一个名为 mrh.csv 的 CSV 文件,其中前两行代表标题:

Name,Height,Age
"",Metres,""
A,-1,25
B,95,-1

我正在使用以下代码将其读入 DataFrame:

import pandas as pd
pd.read_csv('mrh.csv', header=[0,1], na_values=[-1,''])

这会产生一个包含以下内容的数据框:

    Name                Height  Age
    Unnamed: 0_level_1  Metres  Unnamed: 2_level_1

0   A                   NaN     25.0
1   B                   95.0    NaN

使用 read_csv 的 na_values 参数,我可以在文件中将缺失值标记为 -1,但缺失的标题行值在标记为“”(我也尝试过 -1)时显示为 未命名: x_level_y(如果使用它,则为 -1)。

有没有办法不显示缺失值 - 删除 Unnamed: x_level_y 或用有意义的值替换它?

所需的输出 1:

    Name  Height  Age
          Metres    

0   A     NaN     25.0
1   B     95.0    NaN

所需的输出 2:

    Name  Height  Age
    -     Metres  - 

0   A     NaN     25.0
1   B     95.0    NaN

【问题讨论】:

  • a meaningful value 是什么意思,你能显示你想要得到的输出吗?
  • @Dark 我已经用所需的输出更新了问题。

标签: python pandas csv dataframe


【解决方案1】:

您可以创建新的 MultiIndex 并分配给columns

df = pd.read_csv('mrh.csv', header=[0,1], na_values=[-1,''])

a = df.columns.get_level_values(level=0)
b = df.columns.get_level_values(level=1).str.replace('Un.*','')
df.columns = [a, b]
print (df)
  Name Height   Age
       Metres      
0    A    NaN  25.0
1    B   95.0   NaN

或者:

a = df.columns.get_level_values(level=0)
b = df.columns.get_level_values(level=1).str.replace('Un.*','-')
df.columns = [a, b]
print (df)
  Name Height   Age
     - Metres     -
0    A    NaN  25.0
1    B   95.0   NaN

【讨论】:

  • 这个和我的差不多
  • 嗯,你生气了吗?因为我认为不是,但我向您保证,如果您愿意,可以将此解决方案添加到您的答案中,然后我将其删除。
  • 好吧,让它留下来。我的仍然指向需要修复的错误。
【解决方案2】:

我认为使用 read_csv 是不可能的,您可以在加载后修改索引:

from io import StringIO

txt = '''Name,Height,Age
"",Metres,""
A,-1,25
B,95,-1'''

df = pd.read_csv(StringIO(txt),header=[0,1],na_values=['-1',''])

df.columns = df.columns.set_levels(df.columns.get_level_values(level=1).str.replace('Un.*',''),level=1)
df.columns = df.columns.set_levels(df.columns.get_level_values(level=1).str.replace('Un.*',''),level=1)

输出:

   Name Height   Age
        Metres      
0    A    NaN  25.0
1    B   95.0   NaN

要知道分配 df.columns 两次,您可以查看here。还是很神秘的

编辑,set_levels 仍然有问题,您可以使用:

df.columns = df.columns.set_levels(df.columns.levels[1].str.replace('Un.*', ''), level=1)

【讨论】:

  • 好像是bug,最后一行应该是df.columns = df.columns.set_levels(df.columns.get_level_values(level=1),level=1)
  • @jezrael 您可以查看我发布问题的链接,让我等到错误修复。我正在等待我的问题的答案
  • 我真的很喜欢答案,但不知道如何;)
  • 但我认为如果您的解决方案有问题,最好不要使用它;)
  • @jezrael 我们修复它怎么样。还是不错的功能,只是需要更新一些bug。
【解决方案3】:
import pandas as pd
pd.read_csv("mrh.csv").fillna("-").to_csv("mrh.csv",index=None)
df1 = pd.read_csv("mrh.csv",header=[0,1],na_values=[-1,''])
df1

输出:

   Name Height  Age
   -    Metres  -
0   A   NaN    25.0
1   B   95     NaN

【讨论】:

  • 如果可能的话,我想避免修改原始文件。
  • 虽然此代码 sn-p 可能是解决方案,但包含解释确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因
猜你喜欢
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-25
相关资源
最近更新 更多