【问题标题】:How to read unstructured csv in pandas如何在熊猫中读取非结构化 csv
【发布时间】:2016-03-10 09:02:41
【问题描述】:

我有一个乱七八糟的 csv 文件(只是扩展名是 csv)。但是当我在 ms excel 中以; 分隔时打开此文件时,它看起来如下所示(虚拟样本)-

我调查了这个文件并发现了以下内容:

  1. 某些列有名称,而其他列没有。
  2. 行的长度是可变的,但包含换行符以触发下一行开始。

问题:

我如何在 pandas 中读取此表,而所有现有列(标题)仍然存在,空白列填充有连续数字,关心可变长度的行。

事实上,我想一次又一次地取 8 个单元格值,直到任何行用完为止。从无标题列进行分析。

注意我在read_csv 中尝试过usecols,names,skiprows,sep 等,但没有成功

编辑

添加了示例输入和预期输出(格式更差,但 pandas.read_clipboard()应该可以工作)

输入

car_id   car_type    entry_gate  entry_time(ms)  exit_gate   exit_time(ms)   traveled_dist(m)    avg_speed(m/s)  trajectory(x[m]    y[m]    speed[m/s]  a_tangential[ms-2]  a_lateral[ms-2] timestamp[ms]   )                                           
24   Bus    25  4300    26  48520   118.47  2.678999    509552.78   5039855.59  10.074  0.429   0.2012  0   509552.97   5039855.57  10.0821 0.3853  0.2183  20                      
25   Car    25  20  26  45900   113.91  2.482746    509583.7    5039848.78  4.5344  -0.1649 0.2398  0   509583.77   5039848.71                                      
26   Car     -   -   -   -  109.68  8.859805    509572.75   5039862.75  4.0734  -0.7164 -0.1066 0   509572.67   5039862.76  4.0593  -0.7021 -0.1141 20  509553.17   5039855.55  10.0886 0.2636  0.2356  40
27   Car     -   -   -   -  119.84  3.075936    509582.73   5039862.78  1.191   0.5247  0.0005  0   509582.71   5039862.78  1.2015  0.5322                              
28   Car     -   -   -   -  129.64  4.347466    509591.07   5039862.9   1.6473  0.1987  -0.0033 0   509591.04   5039862.89  1.6513  0.2015  -0.0036 20  

预期的输出(数据帧)

car_id   car_type    entry_gate  entry_time(ms)  exit_gate   exit_time(ms)   traveled_dist(m)    avg_speed(m/s)  trajectory(x[m]    y[m]    speed[m/s]  a_tangential[ms-2]  a_lateral[ms-2] timestamp[ms]   1   2   3   4   5   6   7   8   9   10  11  12
24   Bus    25  4300    26  48520   118.47  2.678999    509552.78   5039855.59  10.074  0.429   0.2012  0   509552.97   5039855.57  10.0821 0.3853  0.2183  20                      
25   Car    25  20  26  45900   113.91  2.482746    509583.7    5039848.78  4.5344  -0.1649 0.2398  0   509583.77   5039848.71                                      
26   Car     -   -   -   -  109.68  8.859805    509572.75   5039862.75  4.0734  -0.7164 -0.1066 0   509572.67   5039862.76  4.0593  -0.7021 -0.1141 20  509553.17   5039855.55  10.0886 0.2636  0.2356  40
27   Car     -   -   -   -  119.84  3.075936    509582.73   5039862.78  1.191   0.5247  0.0005  0   509582.71   5039862.78  1.2015  0.5322                              
28   Car     -   -   -   -  129.64  4.347466    509591.07   5039862.9   1.6473  0.1987  -0.0033 0   509591.04   5039862.89  1.6513  0.2015  -0.0036 20      

【问题讨论】:

  • 能否提供输入文件的示例 sn-p 和所需的输出,因为我建议在将数据传递给 pandas 之前进行一些预处理。

标签: python csv pandas dataframe


【解决方案1】:

预处理

函数get_names() 打开文件,检查分割行的最大长度。 然后我读取第一行并从最大长度添加缺失值。

第一行的最后一个值是),所以我用firstline[:-1]删除它,然后我添加 以+1rng = range(1, m - lenfirstline + 2) 为缺失列的范围。 +2 是因为范围从值1 开始。

然后您可以使用函数read_csv,跳过第一行并作为名称使用get_names() 的输出。

import pandas as pd
import csv
 
#preprocessing
def get_names():
    with open('test/file.txt', 'r') as csvfile:
        reader = csv.reader(csvfile)
        num = []
        for i, row in enumerate(reader):
            if i ==0:
                firstline = ''.join(row).split()
                lenfirstline = len(firstline)
                #print firstline, lenfirstline
            num.append(len(''.join(row).split()))
        m = max(num)
        rng = range(1, m - lenfirstline + 2)
        #remove )
        rng = firstline[:-1] + rng
        return rng

#names is list return from function
df = pd.read_csv('test/file.txt', sep="\s+", names=get_names(), index_col=[0], skiprows=1)
#temporaly display 10 rows and 30 columns
with pd.option_context('display.max_rows', 10, 'display.max_columns', 30):
    print df
        
       car_type entry_gate entry_time(ms) exit_gate exit_time(ms)  \
car_id                                                              
24          Bus         25           4300        26         48520   
25          Car         25             20        26         45900   
26          Car          -              -         -             -   
27          Car          -              -         -             -   
28          Car          -              -         -             -   

        traveled_dist(m)  avg_speed(m/s)  trajectory(x[m]        y[m]  \
car_id                                                                  
24                118.47        2.678999        509552.78  5039855.59   
25                113.91        2.482746        509583.70  5039848.78   
26                109.68        8.859805        509572.75  5039862.75   
27                119.84        3.075936        509582.73  5039862.78   
28                129.64        4.347466        509591.07  5039862.90   

        speed[m/s]  a_tangential[ms-2]  a_lateral[ms-2]  timestamp[ms]  \
car_id                                                                   
24         10.0740              0.4290           0.2012              0   
25          4.5344             -0.1649           0.2398              0   
26          4.0734             -0.7164          -0.1066              0   
27          1.1910              0.5247           0.0005              0   
28          1.6473              0.1987          -0.0033              0   

                1           2        3       4       5   6          7  \
car_id                                                                  
24      509552.97  5039855.57  10.0821  0.3853  0.2183  20        NaN   
25      509583.77  5039848.71      NaN     NaN     NaN NaN        NaN   
26      509572.67  5039862.76   4.0593 -0.7021 -0.1141  20  509553.17   
27      509582.71  5039862.78   1.2015  0.5322     NaN NaN        NaN   
28      509591.04  5039862.89   1.6513  0.2015 -0.0036  20        NaN   

                 8        9      10      11  12  
car_id                                           
24             NaN      NaN     NaN     NaN NaN  
25             NaN      NaN     NaN     NaN NaN  
26      5039855.55  10.0886  0.2636  0.2356  40  
27             NaN      NaN     NaN     NaN NaN  
28             NaN      NaN     NaN     NaN NaN  

后处理

首先您必须估计最大列数N。我知道他们的真实号码是26,所以我估计为N = 30。带有参数name = range(N) 的函数read_csv 返回NaN 列,列的估计长度和实际长度有什么区别。

删除后,您可以选择具有列名称的第一行,其中不是NaN(我删除最后一列) by [:-1])-df1.loc[0].dropna()[:-1]。 然后,您可以在第一行附加范围从 1 到长度为 NaN 值的新系列。 最后第一行被df 的子集删除。

#set more as estimated number of columns
N = 30
    
df1 = pd.read_csv('test/file.txt', sep="\s+", names=range(N))

df1 = df1.dropna(axis=1, how='all')  #drop columns with all NaN

df1.columns = df1.loc[0].dropna()[:-1].append(pd.Series(range(1, len(df1.columns) - len(df1.loc[0].dropna()[:-1]) + 1 )))

#remove first line with uncomplete column names
df1 = df1.ix[1:]
print df1.head()

【讨论】:

  • 添加了后期处理方法,也许这会更有帮助。
  • 工作量减少后我会尽快更新。
猜你喜欢
  • 1970-01-01
  • 2017-08-20
  • 2018-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-23
相关资源
最近更新 更多