2017-01-16 90 views
1

修改某些行,我有一個數據幀像這樣Python的熊貓複製和數據幀

Names;  Count; PartNr 
R1, R2,...Rn; n;  1234-5678 
C1, C2;  2;  1234-6789 

名單應導出爲CSV文件導入在其他專有軟件。該軟件在「名稱」列中最多可接受100個字符,如果有更多的數據,我應該包裝現有的行,複製整個列並添加剩餘的名稱。所以在名稱列中應該有最多100個字符的多行。零件的絕對計數應該只在第一行,所以計數值應該設置爲零。

Names;    Count; PartNr 
R1, R2,...Ra;  n;  1234-5678 
Ra+1, Ra+2,...Rb; 0;  1234-5678 
Rb+1, Rb+2,...Rn; 0;  1234-5678 
C1, C2;    2;  1234-6789 

有沒有一種很好的方法,直接在熊貓中修改?

我試着遍歷行,但我不允許修改我正在迭代的數據框,所以這是行不通的。有更好的解決方案

數據幀長度從10到1000倍,只有少數幾行的名稱太長,所以性能並不重要。

+0

你試過迭代通過'df_copy = df.copy()'而不是原始數據幀'df'嗎? – Kris

+0

你的意思是複製原來的,然後迭代和追加?聽起來不錯,我會嘗試。 –

+1

此外,如果您可以「包裝」Rn值,那麼您是否有理由不在每一行上放置單個值? – Kris

回答

1

我不認爲有一個特別好的方式來做到這一點熊貓。 每當DataFrame包含一列列表,並且您想要執行某種需要迭代列表的計算時,您不得不爲列中的每個項目(即列表)調用一次Python函數。由於沒有辦法在這裏應用Pandas的快速矢量化操作,這會傷害性能。如果可能,故事的寓意是避免將列表放入DataFrame中。

(當然,你的情況,似乎要在特定的 格式的另一個應用程序準備CSV。因此,如果需要列出一個數據幀,所以 它。)

正如你上面提到的,你可以遍歷行。您可以使用iterrowsitertuples。我會用itertuples,因爲它往往是更快:

import itertools as IT 
import numpy as np 
import pandas as pd 

Rs = ['R{}'.format(i) for i in range(1,251)] 
Cs = ['C1', 'C2'] 
df = pd.DataFrame({'Names': [Rs, Cs], 'Count': ['n',0], 
        'PartNr':['1234-5678','1234-6789']}) 

def chunks(seq, n): 
    # http://stackoverflow.com/a/312464/190597 (Ned Batchelder) 
    """ Yield successive n-sized chunks from seq.""" 
    for i in range(0, len(seq), n): 
     yield seq[i:i + n] 

result = [] 
for row in df.itertuples(): 
    result.append(pd.DataFrame({'Names': list(chunks(row.Names, 100)), 
          'Count':row.Count, 
          'PartNr':row.PartNr})) 

result = pd.concat(result, axis=0, ignore_index=True) 
print(result) 

產生

Count            Names  PartNr 
0  n [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11,... 1234-5678 
1  n [R101, R102, R103, R104, R105, R106, R107, R10... 1234-5678 
2  n [R201, R202, R203, R204, R205, R206, R207, R20... 1234-5678 
3  0           [C1, C2] 1234-6789 

itertuplesfor-loop內部,一個新的數據幀構成的每一行。 DataFrames被收集到名爲result的列表中。在完成for-loop 後,DataFrames列表被連接成一個DataFrame。