Python 熊猫-在多个列上工作似乎很慢
我在处理大熊猫的csv时遇到了一些问题。Csv由一个索引和大约450列组成,每组3列,如下所示:Python 熊猫-在多个列上工作似乎很慢,python,performance,csv,pandas,lambda,Python,Performance,Csv,Pandas,Lambda,我在处理大熊猫的csv时遇到了一些问题。Csv由一个索引和大约450列组成,每组3列,如下所示: cola1 colb1 colc1 cola2 colb2 colc2 cola3 colb3 colc3 1 stra_1 ctrlb_1 retc_1 stra_1 ctrlb_1 retc_1 stra_1 ctrlb_1 retc_1 2 stra_2 ctrlb_2 retc_2 stra_2 ctrlb_2 re
cola1 colb1 colc1 cola2 colb2 colc2 cola3 colb3 colc3
1 stra_1 ctrlb_1 retc_1 stra_1 ctrlb_1 retc_1 stra_1 ctrlb_1 retc_1
2 stra_2 ctrlb_2 retc_2 stra_2 ctrlb_2 retc_2 stra_2 ctrlb_2 retc_2
3 stra_3 ctrlb_3 retc_3 stra_3 ctrlb_3 retc_3 stra_3 ctrlb_3 retc_3
对于每三个列,我想“分析B列(它是一种“控制字段”),根据它的值,我应该通过处理a列和C列返回一个值
最后,我需要返回从150到1的所有结果列的串联
我已经尝试过apply,但它似乎太慢了(处理50k行需要10分钟)
通过示例函数,您可以在此处找到:
我试着提取一个cola、colb、colc的独特组合列表-对列表进行预处理-并应用map生成结果,它加快了一点速度:
for i in range(1,151):
df['Concat' + str(i)] = df['cola' + str(i)] + '|' + df['colb' + str(i)] + '|' + df['colc' + str(i)]
concats = []
for i in range(1,151):
concats.append('Concat' + str(i))
ret = df[concats].values.ravel()
uniq = list(set(ret))
list = {}
for member in ret:
list[member] = getPath2(member)
for i in range(1,MAX_COLS + 1):
df['Res' + str(i)] = df['Concat' + str(i)].map(list)
df['Path'] = df.apply(getFullPath2,axis=1)
函数getPath和getFullPath2定义如下:
但它似乎仍然有点慢(处理所有内容需要6分钟)
您对如何加快csv处理有何建议?
我甚至不知道我使用的“连接”列的方法是否更好:),尝试了Series.cat,但我不知道如何只链接一些列,而不是完整的df
非常感谢!
Mic修改后的答案:我从你的标准中看到,实际上你在每列上都有多个控件。我认为有效的方法是将这些控件拆分为3个数据帧,应用你的映射如下:
import pandas as pd
series = {
'cola1': pd.Series(['D_1','C_1','E_1'],index=[1,2,3]),
'colb1': pd.Series(['ret1','ret1','ret2'],index=[1,2,3]),
'colc1': pd.Series(['B_1','C_2','B_3'],index=[1,2,3]),
'cola2': pd.Series(['D_1','C_1','E_1'],index=[1,2,3]),
'colb2': pd.Series(['ret3','ret1','ret2'],index=[1,2,3]),
'colc2': pd.Series(['B_2','A_1','A_3'],index=[1,2,3]),
'cola3': pd.Series(['D_1','C_1','E_1'],index=[1,2,3]),
'colb3': pd.Series(['ret2','ret2','ret1'],index=[1,2,3]),
'colc3': pd.Series(['A_1','B_2','C_3'],index=[1,2,3]),
}
your_df = pd.DataFrame(series, index=[1,2,3], columns=['cola1','colb1','colc1','cola2','colb2','colc2','cola3','colb3','colc3'])
# Split your dataframe into three frames for each column type
bframes = your_df[[col for col in your_df.columns if 'colb' in col]]
aframes = your_df[[col for col in your_df.columns if 'cola' in col]]
cframes = your_df[[col for col in your_df.columns if 'colc' in col]]
for df in [bframes, aframes, cframes]:
df.columns = ['col1','col2','col3']
# Mapping criteria
def map_colb(c):
if c == 'ret1':
return 'A'
elif c == 'ret2':
return None
else:
return 'F'
def map_cola(a):
if a.startswith('D_'):
return 'D'
else:
return 'E'
def map_colc(c):
if c.startswith('B_'):
return 'B'
elif c.startswith('C_'):
return 'C'
elif c.startswith('A_'):
return None
else:
return 'F'
# Use it on each frame
aframes = aframes.applymap(map_cola)
bframes = bframes.applymap(map_colb)
cframes = cframes.applymap(map_colc)
# The trick here is filling 'None's from the left to right in order of precedence
final = bframes.fillna(cframes.fillna(aframes))
# Then just combine them using whatever delimiter you like
# df.values.tolist() turns a row into a list
pathlist = ['|'.join(item) for item in final.values.tolist()]
这产生了以下结果:
In[70]: pathlist
Out[71]: ['A|F|D', 'A|A|B', 'B|E|A']
非常感谢,我很快就会尝试你的方法。你可以在第一篇文章的pasebin链接中找到一个criteria/dataset的小例子,我会让你不断更新!据我所知,applymap只适用于系列。
在我的情况下,困难的部分是从每三列的值中得到一个值:
if(colb1==1):return-cola-else:return-colb
这就是为什么我尝试了applyApplymap也适用于dataframes-elementwise查看:如果上述方法不起作用,您会遇到什么错误?哇,刚刚尝试过,它似乎比我的(更糟糕的)解决方案快了500%左右!很好,很高兴我能提供帮助:)
In[70]: pathlist
Out[71]: ['A|F|D', 'A|A|B', 'B|E|A']