当前位置: 首页 > 知识库问答 >
问题:

由于额外的列值,在尝试使用熊猫Python读取csv时出错

郭华美
2023-03-14

以下是我试图摆脱的场景:
我试图读取以下类型的csv:

para1,para2,para3,para4
1,2,3,4,
1,2,3,4,5,
1,2,3,4,
2,3,4,5,6,7,8,9,0,

我正在使用以下命令并得到以下错误:

>>> import pandas as pd
>>> df =pd.read_csv("test.csv")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python35\lib\site-packages\pandas\io\parsers.py", line 702, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "C:\Python35\lib\site-packages\pandas\io\parsers.py", line 435, in _read
    data = parser.read(nrows)
  File "C:\Python35\lib\site-packages\pandas\io\parsers.py", line 1139, in read
    ret = self._engine.read(nrows)
  File "C:\Python35\lib\site-packages\pandas\io\parsers.py", line 1995, in read
    data = self._reader.read(nrows)
  File "pandas\_libs\parsers.pyx", line 899, in pandas._libs.parsers.TextReader.read
  File "pandas\_libs\parsers.pyx", line 914, in pandas._libs.parsers.TextReader._read_low_memory
  File "pandas\_libs\parsers.pyx", line 968, in pandas._libs.parsers.TextReader._read_rows
  File "pandas\_libs\parsers.pyx", line 955, in pandas._libs.parsers.TextReader._tokenize_rows
  File "pandas\_libs\parsers.pyx", line 2172, in pandas._libs.parsers.raise_parser_error
pandas.errors.ParserError: Error tokenizing data. C error: Expected 4 fields in line 3, saw 5

我试图搜索这个问题,并在SO上得到了这个线程
Python熊猫错误标记化数据

所以,我努力了。这不是我所期望的。它正在截断值。

>>> df =pd.read_csv("test.csv",error_bad_lines=False)
b'Skipping line 3: expected 4 fields, saw 5\nSkipping line 5: expected 4 fields, saw 9\n'
>>> df


para1  para2  para3  para4
0      1      2      3      4
1      1      2      3      4

我想要的是这样的:
如果有额外的值,那么将列作为整数值,并在额外值中找到最高的列。然后将剩余的值设为零(0),直到最后一列并读取csv。

我期望的输出如下:

>>> df =pd.read_csv("test.csv")
>>> df
   para1  para2  para3  para4    0    1    2    3    4
0      1      2      3      4  NaN  NaN  NaN  NaN  NaN
1      1      2      3      4  5.0  NaN  NaN  NaN  NaN
2      1      2      3      4  NaN  NaN  NaN  NaN  NaN
3      2      3      4      5  6.0  7.0  8.0  9.0  0.0
>>> df = df.fillna(0)
>>> df
   para1  para2  para3  para4    0    1    2    3    4
0      1      2      3      4  0.0  0.0  0.0  0.0  0.0
1      1      2      3      4  5.0  0.0  0.0  0.0  0.0
2      1      2      3      4  0.0  0.0  0.0  0.0  0.0
3      2      3      4      5  6.0  7.0  8.0  9.0  0.0

但是请注意,我不想照顾专栏。相反,程序必须自动理解并制作上面给出的列标题。

第二,请尽量避免建议我写标题。因为可能有许多列,我可能无法写入标题,但只是让它保持原样。所以丢失的列标题将是上面所述的整数。有人有任何查询的解决方案,请让我知道?

共有3个答案

温翔宇
2023-03-14

尝试使用下面的代码,使用sep='',然后使用iloc获取第一列,然后简单地使用str.splitexpand=True生成新的数据帧,然后使用fillna替换NaNs,最后一行是用列表和列表(范围(…)命名列

所以你应该使用:

df = pd.read_csv("test.csv", sep='  ')
df2 = df.iloc[:, 0].str.replace(',$', '').str.split(',', expand=True).fillna(0)
dd = df.columns[0].split(',')
ff = [str(x) for x in range(len(df2.columns) - len(dd))]
df2.columns = dd + ff
print(df2)

芮瑾瑜
2023-03-14

好的,这意味着您必须解析文件直到其结束,才能获得实际的列数,因为panda。read_csv没有规定该要求。

如果不考虑高性能(*),一种简单的方法是依赖良好的旧csv模块,并根据需要动态添加列:

with open('test.csv') as fd:
    rd = csv.reader(fd)
    header = next(rd)     # initialize column names from first row
    next_key = 0          # additional columns will start at '0'
    data = {k: list() for k in header}  # initialize data list per column
    for row in rd:
        while len(row) > len(header):    # add eventual new columns
            header.append(str(next_key))
            data[header[-1]] = [np.nan] * len(data[header[0]])
            next_key += 1                # increase next column name
        # eventually extend the row up to the header size
        row.extend([np.nan] * (len(header) - len(row)))
        # and add data to the column lists
        for i, k in enumerate(header): data[k].append(row[i])

# data is now in a dict format, suitable to feed DataFrame
df = pd.DataFrame(data)

(*)上面的代码效率不高,因为它一次向列表中添加一个元素。这对于pandas数据帧来说是很糟糕的,即使对于Python列表也不是很好。它可以通过在numpy中分配束来改进。ndarray但代价是复杂性增加。

松国兴
2023-03-14

我不确定是否有更干净的方法可以做到这一点,但我测试了它,它只使用熊猫:

df = pd.read_csv('test.csv', header=None, sep='\n')
df= df[0].str.split(',', expand=True)
new_header = df.iloc[0].fillna(df.columns.to_series())
df = df[1:]
df.columns = new_header

 类似资料:
  • 问题内容: 这个问题已经在这里有了答案 : Python中的Windows路径 (5个答案) 4年前关闭。 追溯(最近一次通话): 产品中的文件“”,第1行= pd.read_csv(’C:\ amazon_baby.csv’) 在parser_f中的第562行的文件“ C:\ Users \ kvsn \ Anaconda3 \ lib \ site-packages \ pandas \ io

  • 出于某种原因,熊猫在查看某些文件时会抛出错误。csv股票数据我有。以下是错误: Traceback(最近一次调用最后一次):文件"/usr/local/lib/python3.7/site-pack/熊猫/core/index/base.py",第3078行,get_loc返回自己。_engine.get_loc(键)文件"熊猫/_libs/index.pyx",第140行,在熊猫中。_libs.

  • 问题内容: 一个新手。有人可以告诉我为什么在某些情况下在以下函数中的路径名之前使用“ r”吗? 提前致谢 问题答案: 在Python中,反斜杠用于表示特殊字符。 例如,-表示换行符。尝试打印。 Windows上的路径名称中往往带有反斜杠。但是我们希望它们表示实际的反斜杠,而不是特殊字符。 r代表“原始”,将导致字符串中的反斜杠被解释为实际的反斜杠,而不是特殊字符。 例如字面意思是字符。再次尝试打印

  • 我有一个包含日期列的csv文件,该文件中的日期格式为“dd.mm.yy”,当熊猫解析日期时,如果小于或等于12,它将日期理解为一个月,因此05.01.05变成01/05/2005。 我怎样才能解决这个问题 问候

  • 问题内容: 我试图读取通过via 创建的数据框,但得到了。我认为这可能与索引为MultiIndex的事实有关,但我不确定如何处理。 调用了55k行的原始数据框,并通过以下方式创建了该数据框: 如果要使用它,这是输出。 当我对这小部分数据(5行)进行处理时,我得到一个。 这是完整的堆栈: 但是,当我在整个数据帧(55k行)上执行此操作时,我得到一个无效的指针错误,并且IPython内核死亡。有任何想

  • 我已经使用pandas成功创建了一个csv文件。我得到以下错误: Traceback(最近一次调用最后一次):文件"C:\用户\Manoj Kumar\PycharmProjects\trex\venv\lib\site-包\熊猫\core\索引\base.py",第3078行,get_loc返回自己。_engine.get_loc(键)文件"pandas_libs\index.pyx",第140