pandas read_csv та фільтруйте стовпці з використанням колі


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
Щось інше, ваше використання ключових слів headerі namesключових слів є неправильним (ось чому у вашому прикладі відсутній перший рядок. headerОчікує int (за замовчуванням 0) як рядок із заголовком. Оскільки ви даєте "True", що трактується як 1, другий рядок (перший рядок даних) використовується як заголовок і відсутній. Однак імена стовпців правильні, оскільки ви перезаписуєте їх namesаргументом. Але ви можете залишити їх, і перший рядок використовується за іменами стовпців за замовчуванням. Однак це не вирішує вашого початкового питання.
joris

1
Це схоже на usecolsпомилку. Можливо, пов'язане з помилкою 2654 ?
abudis

помилка все ще існує без імен та аргументів заголовка, хороша знахідка.
Andy Hayden

@andy Я ще трохи поткнуся і відправлю його помилкам панди. Я ціную перевірку осудності.
чіп

Відповіді:


113

Відповідь @chip повністю пропускає суть двох аргументів ключового слова.

  • names необхідний лише тоді, коли немає заголовка, і ви хочете вказати інші аргументи, використовуючи імена стовпців, а не цілі індекси.
  • 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додатково.
Мак

Але все-таки використовувати usecolsз цілочисельними індексами стовпці, які потрібно зберегти @Mack?
Mr_and_Mrs_D

22

Цей код досягає того, що ви хочете - також його дивна і, звичайно, глючна помилка:

Я помітив, що це працює, коли:

а) ви вказуєте index_colрел. до кількості стовпців, які ви дійсно використовуєте - отже, його три стовпці в цьому прикладі, а не чотири (ви опускаєтеdummy і починаєте відлік з цього моменту)

б) те саме для parse_dates

в) не так для usecols ;) зі зрозумілих причин

г) тут я пристосував те, 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
однак це
марне

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
Це може бути простіше, але це також значно повільніше. Коли ви працюєте над великими наборами даних (я зараз працюю з одним файлом CSV на 13 ГБ), відсутність необхідності чекати годин, поки файл завантажиться, стає набагато важливішим.
Фальшиве ім'я
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.