熊猫read_csv并使用usecols过滤列


97

我有一个csv文件,pandas.read_csv当我使用过滤列usecols并使用多个索引时,该文件输入不正确。

import pandas as pd
csv = r"""dummy,date,loc,x
   bar,20090101,a,1
   bar,20090102,a,3
   bar,20090103,a,5
   bar,20090101,b,1
   bar,20090102,b,3
   bar,20090103,b,5"""

f = open('foo.csv', 'w')
f.write(csv)
f.close()

df1 = pd.read_csv('foo.csv',
        header=0,
        names=["dummy", "date", "loc", "x"], 
        index_col=["date", "loc"], 
        usecols=["dummy", "date", "loc", "x"],
        parse_dates=["date"])
print df1

# Ignore the dummy columns
df2 = pd.read_csv('foo.csv', 
        index_col=["date", "loc"], 
        usecols=["date", "loc", "x"], # <----------- Changed
        parse_dates=["date"],
        header=0,
        names=["dummy", "date", "loc", "x"])
print df2

我希望df1和df2除了丢失的虚拟列外应该相同,但是这些列的标签错误。日期也被解析为日期。

In [118]: %run test.py
               dummy  x
date       loc
2009-01-01 a     bar  1
2009-01-02 a     bar  3
2009-01-03 a     bar  5
2009-01-01 b     bar  1
2009-01-02 b     bar  3
2009-01-03 b     bar  5
              date
date loc
a    1    20090101
     3    20090102
     5    20090103
b    1    20090101
     3    20090102
     5    20090103

使用列号而不是名称给我同样的问题。我可以通过在read_csv步骤之后删除虚拟列来解决此问题,但是我试图了解出了什么问题。我正在使用熊猫0.10.1。

编辑:修复错误的标头用法。


1
还有一些事情,您对headerand names关键字的用法不正确(这就是示例中缺少第一行的原因。header期望包含int的行作为标头的行。因为您提供的“ True”解释为1,第二行(第一个数据行)用作标题,但丢失了,但是列名是正确的,因为用names参数覆盖了它,但是您都可以保留它们,并且第一行默认用作列名。但是,它不能解决您的第一个问题
joris

1
这看起来像个usecols错误。可能与错误2654有关
2013年

错误仍然没有名称和标头参数,很好的发现。
安迪·海登

@andy我会再戳一点,并将其提交给熊猫bug。我感谢理智检查。
芯片

Answers:


113

@chip的答案完全错过了两个关键字参数的含义。

  • 名称是只在必要时有没有头和要指定使用的列名,而不是整数索引等参数。
  • usecols应该在将整个DataFrame读入内存之前提供过滤器;如果使用得当,则读取后永远不需要删除列。

此解决方案纠正了这些怪异现象:

import pandas as pd
from StringIO import StringIO

csv = r"""dummy,date,loc,x
bar,20090101,a,1
bar,20090102,a,3
bar,20090103,a,5
bar,20090101,b,1
bar,20090102,b,3
bar,20090103,b,5"""

df = pd.read_csv(StringIO(csv),
        header=0,
        index_col=["date", "loc"], 
        usecols=["date", "loc", "x"],
        parse_dates=["date"])

这给了我们:

                x
date       loc
2009-01-01 a    1
2009-01-02 a    3
2009-01-03 a    5
2009-01-01 b    1
2009-01-02 b    3
2009-01-03 b    5

1
这是用于解析CSV数据的教科书解决方案,但是当时我打算使用names参数,因为实际数据没有标题。
筹码

2
在这种情况下,您无需指定header=0。您需要先使用header=None,然后再使用names
Mack

但是仍然usecols要为要保留@Mack的列使用整数索引吗?
Mr_and_Mrs_D

22

这段代码实现了您想要的---也很奇怪,甚至有很多错误:

我观察到它在以下情况下有效:

a)您指定index_col相关。到您实际使用的列数-因此在此示例中为三列,而不是四列(dummy从此开始滴下并开始计数)

b)相同 parse_dates

c)并非usecols出于明显原因;)

d)在这里我改编了names以反映此行为

import pandas as pd
from StringIO import StringIO

csv = """dummy,date,loc,x
bar,20090101,a,1
bar,20090102,a,3
bar,20090103,a,5
bar,20090101,b,1
bar,20090102,b,3
bar,20090103,b,5
"""

df = pd.read_csv(StringIO(csv),
        index_col=[0,1],
        usecols=[1,2,3], 
        parse_dates=[0],
        header=0,
        names=["date", "loc", "", "x"])

print df

哪个打印

                x
date       loc   
2009-01-01 a    1
2009-01-02 a    3
2009-01-03 a    5
2009-01-01 b    1
2009-01-02 b    3
2009-01-03 b    5

1
谢谢。我从来没有想通了的重新排列的正确组合 names基础上和数量usecols等等数据排在正确的。
筹码

8

如果您的csv文件包含额外的数据,则可以在导入后从DataFrame中删除列。

import pandas as pd
from StringIO import StringIO

csv = r"""dummy,date,loc,x
bar,20090101,a,1
bar,20090102,a,3
bar,20090103,a,5
bar,20090101,b,1
bar,20090102,b,3
bar,20090103,b,5"""

df = pd.read_csv(StringIO(csv),
        index_col=["date", "loc"], 
        usecols=["dummy", "date", "loc", "x"],
        parse_dates=["date"],
        header=0,
        names=["dummy", "date", "loc", "x"])
del df['dummy']

这给了我们:

                x
date       loc
2009-01-01 a    1
2009-01-02 a    3
2009-01-03 a    5
2009-01-01 b    1
2009-01-02 b    3
2009-01-03 b    5

为什么在我的情况下index_col造成了问题,我尝试使用您建议的列名,但是如果我通过了列号,它就解决了。
YouAreAwesome

4
但是,这是浪费资源
Mr_and_Mrs_D

0

您只需添加index_col=False参数

df1 = pd.read_csv('foo.csv',
     header=0,
     index_col=False,
     names=["dummy", "date", "loc", "x"], 
     index_col=["date", "loc"], 
     usecols=["dummy", "date", "loc", "x"],
     parse_dates=["date"])
  print df1

-4

首先导入csv并使用csv.DictReader其易于处理...


2
这可能更容易,但也要慢得多。当您处理大型数据集时(我目前正在处理一个13 GB的CSV文件),不必等待数小时来加载文件就变得尤为重要。
假名称
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.