【问题标题】:Python Pandas callable skiprows not taking index from index_colPython Pandas 可调用的跳过不从 index_col 获取索引
【发布时间】:2024-05-29 21:50:01
【问题描述】:

未处理的数据如下所示:

data = "i,a,b\ngood,1,2\nbad,3,a"
df = pd.read_csv(StringIO(data))

  i    a b
--------------
0 good  1 2
1 bad   3 a

使用默认索引正确跳过行:

pd.read_csv(StringIO(data), skiprows=lambda index: 2 == index)

    i    a  b
0   good 1  2

但是,当我使用index_col 设置自己的索引时,这似乎不起作用(不会跳过该行)。

pd.read_csv(StringIO(data), index_col='i', skiprows=lambda index: 'bad' == index)

【问题讨论】:

    标签: python pandas csv dataframe etl


    【解决方案1】:

    它不起作用,因为skiprows中的熊猫按位置省略了行:

    data = "i,a,b\ngood,1,2\nbad,3,a\nbad,a,b\ngood,1,2\nbad,3,a"
    
    df = pd.read_csv(StringIO(data))
    print (df)
          i  a  b
    0  good  1  2
    1   bad  3  a
    2   bad  a  b
    3  good  1  2
    4   bad  3  a
    

    df = pd.read_csv(StringIO(data),skiprows=lambda index: 2 == index)
    print (df)
          i  a  b
    0  good  1  2
    1   bad  a  b
    2  good  1  2
    3   bad  3  a
    
    df = pd.read_csv(StringIO(data),index_col='i', skiprows=lambda index: 2 == index)
    print (df)
          a  b
    i         
    good  1  2
    bad   a  b
    good  1  2
    bad   3  a
    

    什么是更短的方式:

    df = pd.read_csv(StringIO(data),skiprows=[2])
    print (df)
          i  a  b
    0  good  1  2
    1   bad  a  b
    2  good  1  2
    3   bad  3  a
    

    但如果想按名称删除索引:

    df = pd.read_csv(StringIO(data),index_col='i', skiprows=['bad'])
    print (df)
    

    TypeError:需要一个整数

    不工作,没有引发错误:

    df = pd.read_csv(StringIO(data),index_col='i', skiprows=lambda index: 'bad' == index)
    print (df)
          a  b
    i         
    good  1  2
    bad   3  a
    bad   a  b
    good  1  2
    bad   3  a
    
    
    df = pd.read_csv(StringIO(data), skiprows=lambda index: 'bad' == index)
    print (df)
    
          i  a  b
    0  good  1  2
    1   bad  3  a
    2   bad  a  b
    3  good  1  2
    4   bad  3  a
    

    验证来自pandas documentation的示例解决方案:

    df = pd.read_csv(StringIO(data), skiprows=lambda x: x % 2 != 0)
    print (df)
          i  a  b
    0   bad  3  a
    1  good  1  2
    
    df = pd.read_csv(StringIO(data), index_col='i',skiprows=lambda x: x % 2 != 0)
    print (df)
          a  b
    i         
    bad   3  a
    good  1  2
    

    编辑:对跳过位置的预处理数据的可能解决方案:

    df = pd.read_csv('a.csv')
    print (df)
          i  a  b
    0  good  1  2
    1   bad  3  a
    2   bad  a  b
    3  good  1  2
    4   bad  3  a
    
    #preprocessing
    def get_row(data):
        out = []
        with open('a.csv', 'r') as csvfile:
            reader = csv.reader(csvfile)
            for i, row in enumerate(reader):
                if row[0] == data:
                    out.append(i)
        return out
    
    
    skip = get_row('bad')            
    print(skip)
    [2, 3, 5]
    
    df = pd.read_csv('a.csv', skiprows=get_row('bad') )
    print (df)
          i  a  b
    0  good  1  2
    1  good  1  2
    

    【讨论】:

    • 文档说“如果可调用,可调用函数将根据行索引进行评估” - 它是否不适用于新设置的索引?你所说的有记录吗?
    • @DurgaDatta - 是的,我也很惊讶,但最后一次测试它并添加到答案结束。它似乎总是按位置而不是标签名称进行测试。
    • 那么,要通过任意函数跳过行,我们必须在加载数据后执行吗?这也意味着我可以应用 dtype(坏列会使它们失败),并且在转换器函数中也要小心。
    • @DurgaDatta - 我从过去的 Pandas 版本中记住的内容无法通过 read_csv 中的某个值过滤,我认为首先 sentence 在最后一个 pandas 版本中仍然是 True。
    • @DurgaDatta - 添加了可能的解决方案。
    最近更新 更多