pandas 处理数据慢,求好方法

2019-08-14 15:59:42 +08:00
 zky001

各位大佬,我有一个文本,里面有 54 万行数据,其中一列数据是类似 1234,2345,3122,3442 这样的一个字符串,我要把这列数据分割成四列数据,用 split 分割着四列在加一个 pandas dataframe 实现,每次跑半个多小时到一个多小时程序就 down 掉了,有啥好的思路方法完成这样的需求吗?

4849 次点击
所在节点    Python
30 条回复
zky001
2019-08-15 08:57:34 +08:00
@AX5N 实际遍历了 54 万次,但是对每一行都要进行一次裁剪拼加 dataframe 的操作,就很耗时
zky001
2019-08-15 09:01:55 +08:00
@qianc1990 这个数据中列向量还有中文,中文中也有各种逗号,pd 直接读进来会把中文中的逗号也切片进来占用其他数据列
rouwanzi
2019-08-15 09:09:22 +08:00
不要一行行拼,对一列统一操作的时候,可以用 map 或者 pandas 的 apply 这种方法,很久没写过 pandas 的了,具体的细节有点忘记,每行都这样操作 df 肯定慢
zky001
2019-08-15 09:19:51 +08:00
@dongxiao 这个是建立了一个新 dataframe,出来的是裁剪处理后的,可以直接 concat 到原 dataframe 上吗,还要到另一个几十万行的文件中把"1234, 2341, 3412, 3123"这些转换成对应中文
zky001
2019-08-15 09:42:28 +08:00
一列数据是类似 1234,2345,3122,3442 这样的一个字符串,我要把这列数据分割成四列数据,分完后再进另一个去查找,之前写的逻辑代码类似如下:
for u in range(0,products.shape[0]):
start=time.time()
cat1=products.catIds[u].split(',')[0]
#print(categories[categories['catId']==int(cat1)].index[0])
category1=categories['category'][categories[categories['catId']==int(cat1)].index[0]]
cat2=products.catIds[u].split(',')[1]
category2=categories['category'][categories[categories['catId']==int(cat2)].index[0]]
cat3=products.catIds[u].split(',')[-1]
category3=categories['category'][categories[categories['catId']==int(cat3)].index[0]]
df=df.append({"catIds":products.catIds[u],"cat1":category1,"cat2":category2,"cat3":category3})
end=time.time()
print(end-start)
ndf = pd.merge(products,df,how='left',on='catIds'),
rouwanzi
2019-08-15 11:27:54 +08:00
@zky001 大概是这个样子吧,很久没写了
```python
import pandas as pd
from pandas import DataFrame as df

categories = {1:'aa', 2:'bb', 3:'cc', 4:'dd', 5:'ee'}
data = df({'catIds':['1,2,3','2,3,4','3,4,5']})

def process_data(catIds):
ids = catIds.split(',')
cats = [categories.get(int(catId), None) for catId in ids]
return cats

cats = list(map(process_data, data['catIds']))
data[['cat1','cat2','cat3']] = df(cats, index=data.index)
```
cigarzh
2019-08-15 12:53:12 +08:00
Series.apply 啊,现在程序员都不看文档的吗……
yeyu1989
2019-08-15 16:38:19 +08:00
@cigarzh 正解
lmingzhi08
2019-08-15 17:24:43 +08:00
54 万行不算很多...
obj = df['target_col']
objn = obj.str.split(',')
for i in range(4):
df['col_%s' % i] = objn.str[i]

如果再觉得内存不够,分批次处理,每次处理个 1 万行,使用 chunksize
https://blog.csdn.net/zm714981790/article/details/51375475
df_list = pd.read_table('tmp.sv', sep='|', chunksize=4)
for df in df_list:
print(chunk)

如果想要再加速,那么试试多进程,每次后存成一个单独的文件,最后再合并,应该几分钟搞定
Baboonowen
2019-08-15 18:12:55 +08:00
Series.apply 是真的正解

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/591854

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX