熊猫用空白读取多索引csv

Jul*_*rec 4 python csv python-2.7 pandas

我正在努力正确加载一个带有空格的多行标题的csv.CSV看起来像这样:

,,C,,,D,,
A,B,X,Y,Z,X,Y,Z
1,2,3,4,5,6,7,8
Run Code Online (Sandbox Code Playgroud)

CSV标头

我想得到的是:

期望的熊猫标题

当我尝试加载时pd.read_csv(file, header=[0,1], sep=','),我最终得到以下内容:

结果不正确

有没有办法获得理想的结果?


注意:或者,我会接受这样的结果:

替代结果


使用的版本:

  • Python:2.7.8
  • 熊猫0.16.0

unu*_*tbu 8

这是一种修复列索引的自动方法.首先,将列级值拉入DataFrame:

columns = pd.DataFrame(df.columns.tolist())
Run Code Online (Sandbox Code Playgroud)

然后将Unnamed:列重命名为NaN:

columns.loc[columns[0].str.startswith('Unnamed:'), 0] = np.nan
Run Code Online (Sandbox Code Playgroud)

然后向前填充NaN:

columns[0] = columns[0].fillna(method='ffill')
Run Code Online (Sandbox Code Playgroud)

所以columns现在看起来像

In [314]: columns
Out[314]: 
     0  1
0  NaN  A
1  NaN  B
2    C  X
3    C  Y
4    C  Z
5    D  X
6    D  Y
7    D  Z
Run Code Online (Sandbox Code Playgroud)

现在我们可以找到剩余的NaN并用空字符串填充它们:

mask = pd.isnull(columns[0])
columns[0] = columns[0].fillna('')
Run Code Online (Sandbox Code Playgroud)

要创建前两列,A并且可以B索引为- df['A']并且df['B']- 就像它们是单一的 - 你可以交换第一列和第二列中的值:

columns.loc[mask, [0,1]] = columns.loc[mask, [1,0]].values
Run Code Online (Sandbox Code Playgroud)

现在,您可以构建一个新的MultiIndex并将其分配给df.columns:

df.columns = pd.MultiIndex.from_tuples(columns.to_records(index=False).tolist())
Run Code Online (Sandbox Code Playgroud)

把它们放在一起,如果data是的话

,,C,,,D,,
A,B,X,Y,Z,X,Y,Z
1,2,3,4,5,6,7,8
3,4,5,6,7,8,9,0
Run Code Online (Sandbox Code Playgroud)

然后

import numpy as np
import pandas as pd
df = pd.read_csv('data', header=[0,1], sep=',')
columns = pd.DataFrame(df.columns.tolist())
columns.loc[columns[0].str.startswith('Unnamed:'), 0] = np.nan
columns[0] = columns[0].fillna(method='ffill')
mask = pd.isnull(columns[0])
columns[0] = columns[0].fillna('')
columns.loc[mask, [0,1]] = columns.loc[mask, [1,0]].values
df.columns = pd.MultiIndex.from_tuples(columns.to_records(index=False).tolist())
    print(df)
Run Code Online (Sandbox Code Playgroud)

产量

   A  B  C        D      
         X  Y  Z  X  Y  Z
0  1  2  3  4  5  6  7  8
1  3  4  5  6  7  8  9  0
Run Code Online (Sandbox Code Playgroud)