各位大佬,我有一个文本,里面有 54 万行数据,其中一列数据是类似 1234,2345,3122,3442 这样的一个字符串,我要把这列数据分割成四列数据,用 split 分割着四列在加一个 pandas dataframe 实现,每次跑半个多小时到一个多小时程序就 down 掉了,有啥好的思路方法完成这样的需求吗?
1
zky001 OP 想过把这些数据导入数据库处理,但是类似 1234,2345,3122,3442 的数据找不到一个好的对应的数据格式
|
2
liprais 2019-08-14 16:02:13 +08:00 via iPhone
spark 处理完了写进数据库
|
3
Vanderick 2019-08-14 16:23:04 +08:00
read 的时候用 chunksize,此时 df 本质是生成器,然后去迭代读;另外 pandas 有 str.split()内置方法
|
4
ipwx 2019-08-14 16:23:30 +08:00
遇事不决,上 C++。
---- 讲道理你这 54 万行而已,Python for line 都能解决,为啥一定要 pandas dataframe。 |
6
ipwx 2019-08-14 16:50:01 +08:00
@zky001 这样的话我觉得你程序哪里肯定写的不太好。
首先一点可以明确的就是,别的任何其他方案能做到的,C++ 一定也能做到。 ---- 54 万行真的不多,C++ 的话不要用 iostream/fstream,用 fopen/fscanf 甚至是 open/read 然后手工解析。 肯定能优化好的。 |
7
Darcy90 2019-08-14 16:50:15 +08:00
可以试试 dask,话说 54 万行用 apply 不至于这么慢吧
|
8
upczww 2019-08-14 16:57:51 +08:00
Python for 循环绝对要不了那么久,碰巧我刚才处理了一个 200 多万行的文本文件,为什么一分钟不到就处理完了。
|
9
joson1205 2019-08-14 17:00:15 +08:00
肯定是代码算法逻辑有问题,不可能那么久
|
10
dongxiao 2019-08-14 17:00:20 +08:00
import pandas as pd
data = pd.DataFrame(["1234, 2341, 3412, 3123"]*10, columns=["just_a_column"]) ret = data.just_a_column.str.split(", ", expand=True) |
11
Jafee 2019-08-14 17:00:31 +08:00 via iPhone
54 万行不多,跑那么久不太应该,可以看看优化一下代码。
|
12
arrow8899 2019-08-14 17:01:14 +08:00
一行大概多长啊? 再发下代码吧。我本地生成了 100W 行数据,split 然后写入另外一个文件,10 秒钟就完事
|
13
bugcoder 2019-08-14 17:01:41 +08:00
pandas 0.25 的 explode 了解一下
|
14
upczww 2019-08-14 17:03:11 +08:00
楼主可以发一行数据出来看看
|
15
qianc1990 2019-08-14 17:07:13 +08:00
pd.read_csv('file_name', sep=','), 这样不就可以了吗...
|
16
hjq98765 2019-08-14 18:09:52 +08:00
放代码上来,我猜是你不断地 df.append(df)了,pandas 每次生成一个新 df 都会巨慢无比,但是 54w 行也就算个毛毛雨
|
17
zilaijuan 2019-08-14 18:23:07 +08:00 via Android
dataframe 的 map 方法,试一下
|
18
MMMMMMMMMMMMMMMM 2019-08-14 20:46:02 +08:00
用 gpu 跑
N 卡有 cuda,A 卡不太清楚 |
19
lulu00147 2019-08-14 22:11:49 +08:00 via iPhone
Emeditor 正则表达式 了解一下
|
20
AX5N 2019-08-15 00:26:14 +08:00
肯定是你的程序逻辑有问题,你是不是实际上遍历了 54w*54w 次...
|
22
zky001 OP @qianc1990 这个数据中列向量还有中文,中文中也有各种逗号,pd 直接读进来会把中文中的逗号也切片进来占用其他数据列
|
23
rouwanzi 2019-08-15 09:09:22 +08:00
不要一行行拼,对一列统一操作的时候,可以用 map 或者 pandas 的 apply 这种方法,很久没写过 pandas 的了,具体的细节有点忘记,每行都这样操作 df 肯定慢
|
24
zky001 OP @dongxiao 这个是建立了一个新 dataframe,出来的是裁剪处理后的,可以直接 concat 到原 dataframe 上吗,还要到另一个几十万行的文件中把"1234, 2341, 3412, 3123"这些转换成对应中文
|
25
zky001 OP 一列数据是类似 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'), |
26
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) ``` |
27
cigarzh 2019-08-15 12:53:12 +08:00
Series.apply 啊,现在程序员都不看文档的吗……
|
29
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) 如果想要再加速,那么试试多进程,每次后存成一个单独的文件,最后再合并,应该几分钟搞定 |
30
Baboonowen 2019-08-15 18:12:55 +08:00
Series.apply 是真的正解
|