【问题标题】:Overriding 'default' number of fields when reading csv读取 csv 时覆盖“默认”字段数
【发布时间】:2018-07-08 00:12:22
【问题描述】:

以下代码:

import pandas as pd

from StringIO import StringIO
data = StringIO("""a,b,c
               1,2,3
               4,5,6
               6,7,8,9
               1,2,5
               3,4,5""")
pd.read_csv(data, warn_bad_lines=True, error_bad_lines=False)

产生这个输出:

Skipping line 4: expected 3 fields, saw 4

   a  b  c
0  1  2  3
1  4  5  6
2  1  2  5
3  3  4  5

也就是说,第三行被拒绝,因为它包含四个(而不是预期的三个)值。此 csv 数据文件被视为格式错误。

如果我想要一种不同的行为,即不跳过具有比预期更多的字段的行,而是通过使用更大的数据框来保持它们的值,该怎么办。

在给定的示例中,这将是行为('UNK' 只是一个示例,可能是任何其他字符串):

   a  b  c UNK
0  1  2  3 nan
1  4  5  6 nan
2  6  7  8  9
3  1  2  5 nan 
4  3  4  5 nan

这只是一个示例,其中只有一个附加值,那么任意(且先验未知)数量的字段呢?这是否可以通过 pandas read_csv 以某种方式获得?

请注意:我可以使用 csv.reader 来做到这一点,我现在只是想切换到 pandas。

感谢任何帮助/提示。

【问题讨论】:

  • 您还没有在StringIO 构造函数中指定所有列。将StringIO("""a,b,c....""") 更改为StringIO("""a,b,c,ukk...""")
  • 不,我是故意这样做的。这个想法是使用“格式错误”的 csv 文件,其中某些行的字段 nr 大于标题中字段的 nr
  • 那么您的问题需要编辑。
  • 完成,感谢您的帮助。

标签: python python-2.7 pandas csv


【解决方案1】:

在读取 csv 时,您似乎需要 names 参数

import pandas as pd

from StringIO import StringIO
data = StringIO("""a,b,c
               1,2,3
               4,5,6
               6,7,8,9
               1,2,5
               3,4,5""")
df = pd.read_csv(data, warn_bad_lines=True, error_bad_lines=False, names = ["a", "b", "c", "UNK"])

print(df)

输出

                  a  b  c  UNK
0                 a  b  c  NaN
1                 1  2  3  NaN
2                 4  5  6  NaN
3                 6  7  8  9.0
4                 1  2  5  NaN
5                 3  4  5  NaN

【讨论】:

  • 导入应该是from io import StringIO
  • 我承认您的回答在这种情况下有效。但是我不知道有多少列的情况呢?我应该编辑问题以明确添加这种情况吗?
【解决方案2】:

假设Afile.csv 包含:

a,b,c#Incomplete Header
1,2,3
4,5,6
6,7,8,9
1,2,5
3,4,5,,8

以下函数生成一个包含所有字段的 DataFrame:

def readRawValuesFromCSV(file1, separator=',', commentMark='#'):
    df = pd.DataFrame()

    with open(file1, 'r') as f:
        for line in f:
            b = line.strip().split(commentMark)
            if len(b[0])>0:
                lineList = tuple(b[0].strip().split(separator))
                df = pd.concat( [df, pd.DataFrame([lineList])], ignore_index=True )
    return df

您可以使用以下代码对其进行测试:

file1 = 'Afile.csv'
# Read all values of a (maybe malformed) CSV file
df = readRawValuesFromCSV (file1, ',', '#')

产生:

df
   0  1  2    3    4
0  a  b  c  NaN  NaN
1  1  2  3  NaN  NaN
2  4  5  6  NaN  NaN
3  6  7  8    9  NaN
4  1  2  5  NaN  NaN
5  3  4  5         8

感谢herrfz 他在 Handling Variable Number of Columns with Pandas - Python。现在的问题可能是另一个问题的概括。

【讨论】:

    猜你喜欢
    • 2017-04-26
    • 1970-01-01
    • 2011-05-01
    • 2022-11-02
    • 1970-01-01
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    相关资源
    最近更新 更多