我有一个像这样的数据框
Names; Count; PartNr
R1, R2,...Rn; n; 1234-5678
C1, C2; 2; 1234-6789
该列表应导出到csv文件,以便在其他专有软件中导入。该软件在“名称”列中最多接受100个字符,如果有更多数据,我应该包装现有行,复制整列并添加其余名称。因此,Names列中应该有多行,最多100个字符。部件的绝对计数应仅在第一行,因此Count值应设置为零。
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
有一种很好的方法,直接在pandas中修改它吗?
我试图遍历行,但我不允许修改我正在迭代的数据帧,所以这不起作用。有更好的解决方案吗?
数据帧长度为10到1000倍,只有几行名称太长,因此性能不是很重要。
答案 0 :(得分:1)
我不认为在熊猫中有一种特别好的方法可以做到这一点。 每当DataFrame包含一列列表,并且您想要进行某种需要在列表上进行迭代的计算时,您将被迫为列中的每个项(即列表)调用一次Python函数。这会伤害到性能,因为无法应用Pandas'这里快速矢量化操作。故事的寓意是尽可能避免将列表放入DataFrame。
(当然,在您的情况下,您似乎想要在特定的情况下准备CSV 另一个应用的格式。因此,如果需要DataFrame中的列表,那么就是 它)。
正如您所提到的,您可以遍历行。您可以使用iterrows
或itertuples
。我会使用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
在itertuples
for-loop
内,为每一行构建一个新的DataFrame。
DataFrame被收集到名为result
的列表中。在for-loop
之后
完成后,DataFrame的列表将连接成一个DataFrame。