【问题标题】:Python: parse unnamed columns from csvPython:从 csv 解析未命名的列
【发布时间】:2020-01-12 01:29:40
【问题描述】:

我想从以前生成的 csv 文件中正确读取未命名的列。

csv 有一个多索引标题,每列具有不同的形状,例如,第 0 列有一个坐标,第 1 列有两个坐标,第 2 列有三个坐标。因此,在读取完整的 csv 时,未命名的列出现在第 0 列和第 1 列中。 我需要找到具有给定值的行,但我无法传递正确的列。

想象一下 'my.csv' 文件看起来像这样:

C0,C1,C2
,C10,C20
,,C22
-2,0,0.4101
-1,1,0.8058
0,0,0.1000
1,3,0.3846

我试着读一下:

read_df = pd.read_csv('my.csv', header=[0,1,2]) 
print(read_df)

                  C0                 C1      C2
  Unnamed: 0_level_1                C10     C20
  Unnamed: 0_level_2 Unnamed: 1_level_2     C22
0                 -2                  0  0.4101
1                 -1                  1  0.8058
2                  0                  0  0.1000
3                  1                  3  0.3846

我需要选择对应于 C0 值的行,但我最终出现在 KeyError 或 TypeError 中,如下所示:

read_df.loc( read_df[('C0','','')] == 0 )  ## KeyError: ('C0', '', '')

read_df.loc( read_df[('C0','0_level_1','0_level_2')] == 0 ) ## KeyError: ('C0', '0_level_1', '0_level_2')

read_df.loc( read_df[('C0', 'Unnamed: 0_level_1', 'Unnamed: 0_level_2')] == 0 ) ## TypeError: 'Series' objects are mutable, thus they cannot be hashed

一个转变可能是事先命名列并防止这种情况发生,但最好了解如何管理它。

谢谢

PS 这是我生成“my.csv”的方式

import pandas as pd
import random as rnd

col_0 = [('C0', '', '')]
col_1 = [('C1', 'C10','')]
col_2 = [('C2', 'C20', 'C22')]

tot_col = columns=pd.MultiIndex.from_tuples(col_0 + col_1 + col_2)

tot_df = pd.DataFrame(columns=tot_col)

def get_data():
    data_dict = { ('C1','C10','')    : rnd.randint(0,5),
                  ('C2','C20','C22') : '{:2.4f}'.format(rnd.random()) }
    data_df = pd.DataFrame( [data_dict], columns=tot_col )
    return(data_df)

for ii in range(-2, 2):
    ii_df = get_data()
    ii_df[('C0','','')] = ii
    tot_df = pd.concat([tot_df, ii_df], ignore_index=True)

tot_df.to_csv('my.csv', index=False)

【问题讨论】:

  • read_df['C0'] 为我工作。这是期望的输出吗?
  • 这也适用于我。我宁愿需要read_df.loc( read_df['C0'] == 0 )

标签: python pandas csv multi-index


【解决方案1】:

您正在寻找的IIUC

read_df.loc[ read_df[('C0', 'Unnamed: 0_level_1', 'Unnamed: 0_level_2')] == 0 ]

或者干脆

read_df[read_df[('C0', 'Unnamed: 0_level_1', 'Unnamed: 0_level_2')] == 0]

结果:

                  C0                 C1      C2
  Unnamed: 0_level_1                C10     C20
  Unnamed: 0_level_2 Unnamed: 1_level_2     C22
2                  0                  4  0.2373




恢复原始索引有点笨拙:
read_df.columns = pd.MultiIndex.from_tuples([tuple('' if y.startswith('Unnamed:') else y for y in x) for x in map(list, read_df.columns.tolist())])

之后你就可以照常使用了:

read_df[read_df[('C0','','')] == 0]

结果:

  C0  C1      C2
     C10     C20
             C22
2  0   4  0.2373

【讨论】:

    猜你喜欢
    • 2021-12-20
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-25
    • 2015-04-10
    • 1970-01-01
    相关资源
    最近更新 更多