Pandas read_csv不知道是否存在标头

时间:2016-07-13 19:49:47

标签: python csv pandas

我有一个包含已知列的输入文件,比方说两列NameSex。有时它有标题行Name,Sex,有时它不会:

1.csv

Name,Sex
John,M
Leslie,F

2.csv

John,M
Leslie,F

事先了解列的标识,是否有一种很好的方法可以使用相同的read_csv命令处理这两种情况?基本上,我想指定names=['Name', 'Sex'],然后仅在标题出现时才推断header=0。我能想出的最好的是:

  • 1)在执行read_csv之前读取文件的第一行,然后设置 适当的参数。

  • 2)做df = pd.read_csv(input_file, names=['Name', 'Sex']), 然后检查零行是否与标题相同,如果 所以放弃它(然后可能必须重新编号行)。

但这对我来说似乎并不像用例那么不寻常。是否有一种内置的方法可以用read_csv来实现这一点,我没有想过?

2 个答案:

答案 0 :(得分:7)

使用新功能 - selection by callable

cols = ['Name','Sex']

df = (pd.read_csv(filename, header=None, names=cols)
      [lambda x: np.ones(len(x)).astype(bool)
                 if (x.iloc[0] != cols).all()
                 else np.concatenate([[False], np.ones(len(x)-1).astype(bool)])]
)

使用.query()方法:

df = (pd.read_csv(filename, header=None, names=cols)
        .query('Name != "Name" and Sex != "Sex"'))

我不确定这是最优雅的方式,但这也应该有效:

df = pd.read_csv(filename, header=None, names=cols)

if (df.iloc[0] == cols).all():
    df = df[1:].reset_index(drop=True)

答案 1 :(得分:0)

我想出了一种在不事先知道标题名称的情况下检测标题的方法:

if any(df.iloc[0].apply(lambda x: isinstance(x, str))):
    df = df[1:].reset_index(drop=True)

通过稍微更改它,可以使用检测到的标题更新当前标题:

if any(df.iloc[0].apply(lambda x: isinstance(x, str))):
    df = df[1:].reset_index(drop=True).rename(columns=df.iloc[0])

这可以轻松选择所需的行为:

update_header = True

if any(df.iloc[0].apply(lambda x: isinstance(x, str))):
    new_header = df.iloc[0]

    df = df[1:].reset_index(drop=True)

    if update_header:
        df.rename(columns=new_header, inplace=True)

优点:

  • 不需要先了解标题的名称。
  • 如果检测到现有头,可用于自动更新头。

缺点:

  • 如果数据包含字符串,将无法正常工作。除非数据还包含整个字符串行,否则将if any()替换为要求所有元素均为字符串可能会有所帮助。