在Pandas中使用逗号读取CSV文件时出现问题

时间:2018-05-14 10:23:59

标签: python pandas dataframe

Problems reading CSV file with commas and characters in pandas

的扩展程序

上述链接中提供的解决方案可用,当且仅当包含逗号作为其字符和其余列的一列表现良好时。

如果上述问题有多列,该怎么办?

带有其他逗号问题的CSV内容示例:

Name,Age,Address,Phone,Qualification
Suresh,28,Texas,3334567892,B.Tech
Ramesh,24,NewYork, NY,8978974040,9991111234,Ph.D
Mukesh,26,Dallas,4547892345,Ph.D

必需的输出Pandas DataFrame:

Name    Age  Address      Phone                  Qualification
Suresh  28   Texas        3334567892             B.Tech
Ramesh  24   NewYork, NY  8978974040,9991111234  Ph.D
Mukesh  26   Dallas       4547892345             Ph.D

编辑:

以逗号作为连续列中的字符输入文件:

Name,Age,Address,Qualification,Grade                  
Suresh,28,Texas,B.Tech,Ph.D,A
Ramesh,24,NewYork, NY,B.Tech,A+
Mukesh,26,Dallas,B.Tech,Ph.D,A

必需的输出Pandas DataFrame:

Name    Age  Address      Qualification Grade                  
Suresh  28   Texas        B.Tech,Ph.D   A
Ramesh  24   NewYork, NY  B.Tech        A+
Mukesh  26   Dallas       B.Tech,Ph.D   A

我可以获得解决此问题的任何建议吗?

先谢谢!!!

2 个答案:

答案 0 :(得分:3)

执行此操作的一种方法是让"清楚地分隔您的数据 -

Name,Age,Address,Phone,Qualification
Suresh,28,Texas,3334567892,B.Tech
Ramesh,24,"NewYork, NY","8978974040,9991111234",Ph.D
Mukesh,26,Dallas,4547892345,Ph.D

如果不存在,pandas将难以正确阅读。

复制上述数据,执行pd.read_clipboard(sep=','),它将产生 -

     Name  Age      Address                  Phone Qualification
0  Suresh   28        Texas             3334567892        B.Tech
1  Ramesh   24  NewYork, NY  8978974040,9991111234          Ph.D
2  Mukesh   26       Dallas             4547892345          Ph.D

如果整体修改源数据不在您手中 -

一种实用的方法是使用read_csv进行常规error_bad_lines=False。完成后,查看日志并记下pandas正在努力阅读的行,并相应地修改这些行。

希望这有帮助。

答案 1 :(得分:2)

您的数据对于前两列和最后一列都是固定的,因此可以删除这些数据,并使用itertools.groupby()处理剩余的值,以将其余列分组为数字或非数字组。然后可以将结果数据加载到pandas中:

import pandas as pd
from itertools import groupby
import csv

data = []

with open('input.csv', newline='') as f_input:
    csv_input = csv.reader(f_input)
    header = next(csv_input)

    for row in csv_input:
        addr_phone = [','.join(g) for k, g in groupby(row[2:-1], lambda x: x.isdigit())]
        data.append(row[:2] + addr_phone + [row[-1]])

df = pd.DataFrame(data, columns=header)        
print(df)

给你:

     Name Age      Address                  Phone Qualification
0  Suresh  28        Texas             3334567892        B.Tech
1  Ramesh  24  NewYork, NY  8978974040,9991111234          Ph.D
2  Mukesh  26       Dallas             4547892345          Ph.D

要使用第二个示例,您必须决定拆分两列的方法。我建议你创建一份可能的资格列表。当匹配时,您将能够在该点进行拆分。例如:

import pandas as pd
import csv

def find_split(data):
    for index, v in enumerate(data):
        if v.lower() in ['b.tech', 'ph.d']:
            return [', '.join(data[:index]), ', '.join(data[index:])]
    return [', '.join(data), '']

data = []

with open('input.csv', newline='') as f_input:
    csv_input = csv.reader(f_input, skipinitialspace=True)
    header = next(csv_input)

    for row in csv_input:
        data.append(row[:2] + find_split(row[2:-1]) + [row[-1]])

df = pd.DataFrame(data, columns=header)        
print(df)

给你:

     Name Age      Address Qualification Grade
0  Suresh  28        Texas  B.Tech, Ph.D     A
1  Ramesh  24  NewYork, NY        B.Tech    A+
2  Mukesh  26       Dallas  B.Tech, Ph.D     A

您可以首先根据set()(小写)的内容创建row[2]来创建资格列表。打印集的内容,然后将其添加到脚本中并重新运行。