使用其他逗号将数据导入DataFrame

时间:2015-07-10 21:17:25

标签: python pandas dataframe

我有一个数据文件:

ID,ORIG,TIME,TEXT
364,1,7-10-15,This works fine
16254,1,7-10-15,But, I don't work :(
9846,0,7-10-15,Neither, do, I  

当我使用pandas导入时,我试图获得以下内容:

+-------+------+---------+----------------------+
| ID    | ORIG | TIME    | TEXT                 |
+=======+======+=========+======================+
| 3464  | 1    | 7-10-15 | This works fine      |
+-------+------+---------+----------------------+
| 16254 | 1    | 7-10-15 | But, I don't work :( |
+-------+------+---------+----------------------+
| 9846  | 0    | 7-10-15 | Neither, do, I       |
+-------+------+---------+----------------------+

使用我的脚本data_df = pd.read_csv('data.csv', low_memory=False),当我导入第一行时一切正常(没有设置索引)。

然而对于第二行,因为那里有一个逗号,最初在ID中的数据移动到索引列,所有内容都向左移动1。

+-------+----+---------+-----------------+-----------------+
|       | ID | ORIG    | TIME            | TEXT            |
+=======+====+=========+=================+=================+
| 3464  | 1  | 7-10-15 | This works fine | NaN             |
+-------+----+---------+-----------------+-----------------+
| 16254 | 1  | 7-10-15 | But             | I don't work :( |
+-------+----+---------+-----------------+-----------------+

重复模式,在最后一列中找到更多逗号。一个可能的solution就是重写文件,但我试图找到一种方法来简单地导入它而不必重写每个文件(我有大约65 +)。

我的问题是:

是否可以将(第一列)第一列导入“ID”第二列,将“ORIG”第三列导入“TIME”,将其他所有内容导入“TEXT”?

3 个答案:

答案 0 :(得分:4)

您的CSV格式错误,因为它不使用引号来区分逗号,这些逗号是逗号,而逗号是字段值的一部分。

但是,我们可以遍历CSV行并使用str.split(',', 3)在前三个逗号上分割

lines = (line.split(',',3) for line in f)

我们可以将此迭代器直接传递给pd.DataFrame

df = pd.DataFrame(lines, columns=header)

使用pd.read_csv的优化解析引擎加载有效CSV的速度不会很快,但考虑到输入结果不正确,我认为结果非常好。

import numpy as np
import pandas as pd

with open('data', 'r') as f:
    header = [item.strip() for item in next(f).split(',')]
    lines = (line.split(',', 3) for line in f)
    df = pd.DataFrame(lines, columns=header)
    df = df.convert_objects(convert_numeric=True)
    df['TIME'] = pd.to_datetime(df['TIME'])

print(df)

产量

      ID  ORIG       TIME                    TEXT
0    364     1 2015-07-10       This works fine\n
1  16254     1 2015-07-10  But, I don't work :(\n
2   9846     0 2015-07-10        Neither, do, I  

print(df.dtypes)
# ID               int64
# ORIG             int64
# TIME    datetime64[ns]
# TEXT            object
# dtype: object

答案 1 :(得分:2)

这有点难看,但你可以使用DataFrame.from_records使用即时数据:

crap = [l.split(',')[: 3] + [''.join(l.strip().split(',')[3: ])] \
     for l in open('stuff.csv').readlines()]
>> pd.DataFrame.from_records(crap[1: ], columns=crap[0])
      ID ORIG     TIME                 TEXT
0    364    1  7-10-15      This works fine
1  16254    1  7-10-15  But I don't work :(
2   9846    0  7-10-15         Neither do I

答案 2 :(得分:1)

虽然有几种方法可以强制它完全适用于大熊猫,但是使用csv这样做要容易得多,我只是这样做:

import csv, io, pandas as pd
data = io.StringIO()
with open("leb.csv", newline="") as fp:
    reader = csv.reader(fp)
    rows = [row[:3] + [','.join(row[3:])] for row in reader]
    writer = csv.writer(data)
    writer.writerows(rows)

data.seek(0)
df = pd.read_csv(data)

这有效地修复了大熊猫看到之前的输入数据。这给了

>>> df
      ID  ORIG     TIME                  TEXT
0    364     1  7-10-15       This works fine
1  16254     1  7-10-15  But, I don't work :(
2   9846     0  7-10-15        Neither, do, I