pandas read_csv和使用usecols过滤列

时间:2013-02-22 04:50:56

标签: python pandas csv csv-import

当我使用pandas.read_csv过滤列并使用多个索引时,我的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步骤之后删除虚拟列来解决此问题,但我正在尝试了解出现了什么问题。我正在使用pandas 0.10.1。

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

5 个答案:

答案 0 :(得分:79)

@chip的答案完全忽略了两个关键字参数的重点。

    仅当没有标题并且您希望使用列名而不是整数索引指定其他参数时,才需要
  • 名称
  • usecols 应该在将整个DataFrame读入内存之前提供过滤器;如果使用得当,读取后永远不需要删除列。

这个解决方案纠正了这些奇怪之处:<​​/ p>

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 :(得分:19)

这段代码实现了你想要的东西 - 也是它的奇怪而且肯定是错误的:

我发现它在以下情况下有效:

a)您指定index_col rel。你真正使用的列数 - 所以这个例子中的三列,而不是四列(你放弃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

答案 2 :(得分:8)

如果您的csv文件包含额外数据,则导入后DataFrame中的列可以是deleted

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

答案 3 :(得分: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 :(得分:-4)

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