我将csv文件中的多行带空白的表头正确加载是有困难的。CSV文件如下:
,,C,,,D,,
A,B,X,Y,Z,X,Y,Z
1,2,3,4,5,6,7,8
我想要的结果是:
当我尝试使用
pd.read_csv(file, header=[0,1], sep=',')
加载时,我得到了以下结果:是否有方法可以获得想要的结果?
注意:或者,我会接受这个结果作为一个结果。
版本信息:
Python: 2.7.8
Pandas 0.16.0
我将csv文件中的多行带空白的表头正确加载是有困难的。CSV文件如下:
,,C,,,D,,
A,B,X,Y,Z,X,Y,Z
1,2,3,4,5,6,7,8
pd.read_csv(file, header=[0,1], sep=',')
加载时,我得到了以下结果:这里有一种自动化的方式来修复列索引。首先,将列级别的值提取到DataFrame中:
columns = pd.DataFrame(df.columns.tolist())
然后将Unnamed:
列重命名为NaN
:
columns.loc[columns[0].str.startswith('Unnamed:'), 0] = np.nan
然后向前填充 NaN 值:
columns[0] = columns[0].fillna(method='ffill')
因此,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
mask = pd.isnull(columns[0])
columns[0] = columns[0].fillna('')
A
和B
,可以像单层索引一样被索引为df['A']
和df['B']
,您可以交换第一列和第二列中的值:columns.loc[mask, [0,1]] = columns.loc[mask, [1,0]].values
df.columns
:df.columns = pd.MultiIndex.from_tuples(columns.to_records(index=False).tolist())
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
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)
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
并没有什么神奇的方法可以让Pandas知道你希望索引是什么样子,最接近的方式就是自己指定很多东西,像这样:
names = ['A', 'B',
('C','X'), ('C', 'Y'), ('C', 'Z'),
('D','X'), ('D','Y'), ('D', 'Z')]
pd.read_csv(file, mangle_dupe_cols=True,
header=1, names=names, index_col=[0, 1])
提供:
C D
X Y Z X Y Z
A B
1 2 3 4 5 6 7 8
pd.read_csv(file, nrows=1, header=[0,1], index_col=[0, 1])
导入您的 CSV 文件并提供标题行索引:
df = pd.read_csv('file.csv', header=[0, 1, 2])
然后,您可以迭代每个列标题,对其进行清理,将其分配给元组,然后使用 pd.MultiIndex.from_tuples(list_of_tuples)重新分配数据框的列
df.columns = pd.MultiIndex.from_tuples(
[tuple(['' if y.find('Unnamed')==0 else y for y in x]) for x in df.columns]
)
你可以使用以下方式进行阅读:
df = pd.read_csv('file.csv', header=[0, 1], skipinitialspace=True, tupleize_cols=True)
然后
df.columns = pd.MultiIndex.from_tuples(df.columns)
pd.read_csv(file, header=[0,1])
得到的完全相同。 - Julien Marrec加载带有多级索引的数据框:
df = pd.read_csv(filelist,header=[0,1], sep=',')
def replace_index(df):
arr = df.columns.values
l = [list(x) for x in arr]
for i in range(len(l)):
if l[i][0][:7] == 'Unnamed':
if l[i-1][0][:7] != 'Unnamed':
l[i][0] = l[i-1][0]
for i in range(len(l)):
if l[i][0][:7] == 'Unnamed':
l[i][0] = l[i][1]
l[i][1] = ''
index = pd.MultiIndex.from_tuples(l)
df.columns = index
return df
返回正确索引的新数据框:
replace_index(df)
我使用了一种技术,将多级索引列展平为一个列。这对我来说效果很好。
your_df.columns = ['_'.join(col).strip() for col in your_df.columns.values]