2016-09-14 86 views
2

我有兩個分隔符(;)和CSV大熊貓(,)它看起來像這樣:導入CSV與兩個分隔符

vin;vorgangid;eventkm;D_8_lamsoni_w_time;D_8_lamsoni_w_value 
V345578;295234545;13;-1000.0,-980.0;7.9921875,11.984375 
V346670;329781064;13;-960.0,-940.0;7.9921875,11.984375 

我想將它導入到大熊貓的數據幀,與( ;)作爲列分隔符和(,)作爲listarray的分隔符,使用float作爲數據類型。到目前爲止,我正在使用這種方法,但我確信有更容易的東西。使用;作爲分隔符

aa=0; 
csv_import=pd.read_csv(folder+FileName, ';') 
for col in csv_import.columns: 
aa=aa+1 
if type(csv_import[col][0])== str and aa>3: 
    # string to list of strings 
    csv_import[col]=csv_import[col].apply(lambda x:x.split(',')) 
    # make the list of stings into a list of floats 
    csv_import[col]=csv_import[col].apply(lambda x: [float(y) for y in x]) 

回答

3

旁白fr在這裏的其他很好的答案,這是更多的熊貓特定的,應該指出的是,Python本身在字符串處理方面非常強大。你可以只放在一個StringIO對象與','更換​​3210的結果,並從那裏正常工作:

In [8]: import pandas as pd 

In [9]: from cStringIO import StringIO 

In [10]: pd.read_csv(StringIO(''.join(l.replace(';', ',') for l in open('stuff.csv')))) 
Out[10]: 
        vin vorgangid eventkm D_8_lamsoni_w_time \ 
V345578 295234545 13 -1000.0 -980.0   7.992188 
V346670 329781064 13  -960.0 -940.0   7.992188 

        D_8_lamsoni_w_value 
V345578 295234545   11.984375 
V346670 329781064   11.984375 
+0

有趣的方法,這是如何工作在Python 3.5? import io pd.read_csv(io (''.join(l.replace(';',',')for l in open('stuff.csv')))) does not work – valenzio

+0

@valenzio我剛剛在3.5.2上檢查過它,它是一模一樣。 –

+0

我得到按摩,沒有名爲'cStringIO'的模塊 是否必須通過pip安裝該模塊,我有一種感覺它帶有python – valenzio

3

第一讀取CSV:

df = pd.read_csv(filename, sep=';') 

UPDATE:

In [67]: num_cols = df.columns.difference(['vin','vorgangid','eventkm']) 

In [68]: num_cols 
Out[68]: Index(['D_8_lamsoni_w_time', 'D_8_lamsoni_w_value'], dtype='object') 

In [69]: df[num_cols] = (df[num_cols].apply(lambda x: x.str.split(',', expand=True) 
    ....:            .stack() 
    ....:            .astype(float) 
    ....:            .unstack() 
    ....:            .values.tolist()) 
    ....:    ) 

In [70]: df 
Out[70]: 
     vin vorgangid eventkm D_8_lamsoni_w_time  D_8_lamsoni_w_value 
0 V345578 295234545  13 [-1000.0, -980.0] [7.9921875, 11.984375] 
1 V346670 329781064  13 [-960.0, -940.0] [7.9921875, 11.984375] 

In [71]: type(df.loc[0, 'D_8_lamsoni_w_value'][0]) 
Out[71]: float 

OLD答案:

現在,我們可以數分成列表S IN的 「數量」 列:

In [20]: df[['D_8_lamsoni_w_time', 'D_8_lamsoni_w_value']] = \ 
    df[['D_8_lamsoni_w_time', 'D_8_lamsoni_w_value']].apply(lambda x: x.str.split(',')) 
In [21]: df 
Out[21]: 
     vin vorgangid eventkm D_8_lamsoni_w_time  D_8_lamsoni_w_value 
0 V345578 295234545  13 [-1000.0, -980.0] [7.9921875, 11.984375] 
1 V346670 329781064  13 [-960.0, -940.0] [7.9921875, 11.984375] 
+0

謝謝你的建議。我有2條評論: 1)如果你有兩列以上的方式,我想line [20]可以打包成一個for循環,但是它變得和我的方法基本相同,不是嗎? 2)我想最後你還是會得到一串字符串列表,例如型(DF。ix [0,4] [0])=='str' – valenzio

+0

@valenzio,請檢查UPDATE部分 - 我已完全重寫了代碼並解決了您的問題 – MaxU

+0

感謝隊友,這看起來好多了,但你仍然會如果你有第100行的第67行和第68行,需要兩個for循環,我正在尋找類似於Ami Tavory建議的解決方案。基本上,一個導入命令使用正確的參數 – valenzio

2

可以在read_csv使用參數converters和定義自定義功能的分裂:

def f(x): 
    return [float(i) for i in x.split(',')] 

#after testing replace io.StringIO(temp) to filename 
df = pd.read_csv(io.StringIO(temp), 
       sep=";", 
       converters={'D_8_lamsoni_w_time':f, 'D_8_lamsoni_w_value':f}) 
print (df) 
     vin vorgangid eventkm D_8_lamsoni_w_time  D_8_lamsoni_w_value 
0 V345578 295234545  13 [-1000.0, -980.0] [7.9921875, 11.984375] 
1 V346670 329781064  13 [-960.0, -940.0] [7.9921875, 11.984375] 

另一種解決方案與NaN4.5.列工作:

您可以使用read_csv與分隔符;,然後將str.split應用於4.5.列由iloc選擇和listfloat轉換每個值:

import pandas as pd 
import numpy as np 
import io 

temp=u"""vin;vorgangid;eventkm;D_8_lamsoni_w_time;D_8_lamsoni_w_value 
V345578;295234545;13;-1000.0,-980.0;7.9921875,11.984375 
V346670;329781064;13;-960.0,-940.0;7.9921875,11.984375""" 
#after testing replace io.StringIO(temp) to filename 
df = pd.read_csv(io.StringIO(temp), sep=";") 

print (df) 
     vin vorgangid eventkm D_8_lamsoni_w_time D_8_lamsoni_w_value 
0 V345578 295234545  13  -1000.0,-980.0 7.9921875,11.984375 
1 V346670 329781064  13  -960.0,-940.0 7.9921875,11.984375 

#split 4.th and 5th column and convert to numpy array 
df.iloc[:,3] = df.iloc[:,3].str.split(',').apply(lambda x: [float(i) for i in x]) 
df.iloc[:,4] = df.iloc[:,4].str.split(',').apply(lambda x: [float(i) for i in x]) 
print (df) 
     vin vorgangid eventkm D_8_lamsoni_w_time  D_8_lamsoni_w_value 
0 V345578 295234545  13 [-1000.0, -980.0] [7.9921875, 11.984375] 
1 V346670 329781064  13 [-960.0, -940.0] [7.9921875, 11.984375] 

如果需要numpy arrays代替lists

#split 4.th and 5th column and convert to numpy array 
df.iloc[:,3] = df.iloc[:,3].str.split(',').apply(lambda x: np.array([float(i) for i in x])) 
df.iloc[:,4] = df.iloc[:,4].str.split(',').apply(lambda x: np.array([float(i) for i in x])) 
print (df) 
     vin vorgangid eventkm D_8_lamsoni_w_time  D_8_lamsoni_w_value 
0 V345578 295234545  13 [-1000.0, -980.0] [7.9921875, 11.984375] 
1 V346670 329781064  13 [-960.0, -940.0] [7.9921875, 11.984375] 

print (type(df.iloc[0,3])) 
<class 'numpy.ndarray'> 

我儘量提高你的solutiuon:

a=0; 
csv_import=pd.read_csv(folder+FileName, ';') 
for col in csv_import.columns: 
    a += 1 
    if type(csv_import.ix[0, col])== str and a>3: 
     # string to list of strings 
     csv_import[col]=csv_import[col].apply(lambda x: [float(y) for y in x.split(',')]) 
+0

謝謝您的輸入,但如果我錯了,請糾正我,這看起來比我更乏味的方法。乾杯 – valenzio

+0

好吧,我試着改進你的解決方案,請檢查我的答案中的最後一段。 – jezrael

+0

看起來不錯,但我想有沒有辦法避免for循環,我只是認爲有一種方法來初始化導入它會自動知道(',')分隔值是一個數組 – valenzio