【问题标题】:What is a very general way to read-in .csv in Python and pandas?在 Python 和 pandas 中读取 .csv 的一种非常通用的方法是什么?
【发布时间】:2018-03-20 13:18:03
【问题描述】:

我有一个 .csv 文件,其中包含多列长度的行。

import pandas as pd
df = pd.read_csv(infile, header=None)

返回

ParserError: Error tokenizing data. C error: Expected 6 fields in line 8, saw 8

错误。我知道我可以使用

names=my_cols 

read_csv 调用中的选项,但肯定有比这更“pythonic”的东西吗?另外,这不是一个重复的问题,因为

error_bad_lines=False 

导致行被跳过(这是不希望的)。 .csv 看起来像::

Anne,Beth,Caroline,Ernie,Frank,Hannah
Beth,Caroline,David,Ernie
Caroline,Hannah
David,,Anne,Beth,Caroline,Ernie
Ernie,Anne,Beth,Frank,George
Frank,Anne,Caroline,Hannah
George,
Hannah,Anne,Beth,Caroline,David,Ernie,Frank,George

【问题讨论】:

  • 如果没有实际看到您的 csv 的实际样子就无法回答,错误可能是因为您的列名和实际列不匹配,您嵌入了逗号,您的分隔符不是逗号等等。
  • 您希望您的df 是什么样的?
  • 这不是上述问题的重复,因为“error_bad_lines=False”会导致行被跳过。我不想要那种行为。
  • 那么你在这里期待什么?您想要NaN 缺少值吗?您想保留所有行吗?例如,您似乎没有一致的条目数,您必须解析 csv 以确定最大列数,然后在没有标题的情况下读取它
  • 为什么要这样?为什么库必须首先解析整个 csv,然后在第二遍构造 df 知道最大列数?这似乎是一个不合理的假设,而且还不够普遍,不需要

标签: python pandas csv input


【解决方案1】:

好的,受这个相关问题的启发:Pandas variable numbers of columns to binary matrix

所以在 csv 中读取,但将分隔符覆盖为选项卡,这样它就不会尝试拆分名称:

In[7]:
import pandas as pd
import io
t="""Anne,Beth,Caroline,Ernie,Frank,Hannah
Beth,Caroline,David,Ernie
Caroline,Hannah
David,,Anne,Beth,Caroline,Ernie
Ernie,Anne,Beth,Frank,George
Frank,Anne,Caroline,Hannah
George,
Hannah,Anne,Beth,Caroline,David,Ernie,Frank,George"""
df = pd.read_csv(io.StringIO(t), sep='\t', header=None)
df

Out[7]: 
                                                   0
0              Anne,Beth,Caroline,Ernie,Frank,Hannah
1                          Beth,Caroline,David,Ernie
2                                    Caroline,Hannah
3                    David,,Anne,Beth,Caroline,Ernie
4                       Ernie,Anne,Beth,Frank,George
5                         Frank,Anne,Caroline,Hannah
6                                            George,
7  Hannah,Anne,Beth,Caroline,David,Ernie,Frank,Ge...

我们现在可以使用str.splitexpand=True 将名称展开到它们自己的列中:

In[8]:
df[0].str.split(',', expand=True)

Out[8]: 
          0         1         2         3         4       5      6       7
0      Anne      Beth  Caroline     Ernie     Frank  Hannah   None    None
1      Beth  Caroline     David     Ernie      None    None   None    None
2  Caroline    Hannah      None      None      None    None   None    None
3     David                Anne      Beth  Caroline   Ernie   None    None
4     Ernie      Anne      Beth     Frank    George    None   None    None
5     Frank      Anne  Caroline    Hannah      None    None   None    None
6    George                None      None      None    None   None    None
7    Hannah      Anne      Beth  Caroline     David   Ernie  Frank  George

所以为了清楚起见,将您的 read_csv 行修改为:

df = pd.read_csv(infile, header=None, sep='\t')

然后像上面一样执行str.split

【讨论】:

  • (1, 3) 发生了什么事?
  • @GiantsLoveDeathMetal 这些是缺失值,所以看起来它们被视为空/空白字符串,它们可以很容易地替换为None,但感谢您指出这一点
  • 对不起,我是由不一致触发的。 :)
  • 是的,这(我认为!)适用于我想要的。有趣的是,人们可能很想区分空/空白字符串和 NaN/Nones。但这是一个单独的问题(!!)
【解决方案2】:

在使用 pandas 之前,可以对 csv 进行一些操作。

# load data into list
with open('new_data.txt', 'r') as fil:
    data = fil.readlines()

# remove line breaks from string entries
data = [ x.replace('\r\n', '') for x in data]
data = [ x.replace('\n', '') for x in data]

# calculate the number of columns
total_cols = max([x.count(',') for x in data])

# add ',' to end of list depending on how many are needed
new_data = [x + ','*(total_cols-x.count(',')) for x in data]

# save data
with open('save_data.txt', 'w') as outp:
    outp.write('\n'.join(new_data))

# read it in as you did.
pd.read_csv('save_data.txt', header=None)

这是一些粗糙的 python,但应该可以。有时间我会清理的。

或者使用其他答案,它是整洁的。

【讨论】:

  • 在将数据读入主程序之前,我有一个 csv_manipulation 函数没有问题! ;-)
猜你喜欢
  • 2016-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-30
  • 1970-01-01
  • 2013-05-27
相关资源
最近更新 更多