pandas数据框中的列级解析

时间:2019-03-11 06:31:20

标签: python-3.x pandas scikit-learn

目前,我正在处理5列的2000万条记录。我的数据框看起来像-

tran_id   id       code
123        1    1759@1@83@0#1362@0.2600@25.7400@2.8600#1094@1@129.6@14.4
254        1    1356@0.4950@26.7300@2.9700
831        2    1354@1.78@35.244@3.916#1101@2@40@0#1108@2@30@0
732        5    1430@1@19.35@2.15#1431@3@245.62@60.29#1074@12@385.2@58.8#1109
141        2    1809@8@75.34@292.66#1816@4@24.56@95.44#1076@47@510.89@1110.61

所需的输出-

id       new_code
1        1759
1        1362
1        1094
1        1356
2        1354
2        1101
2        1108
5        1430
5        1431
5        1074
5        1109
2        1809
2        1816
2        1076

我到目前为止所做的-

import re
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

dd= pd.DataFrame({'col' : d["code"].apply(lambda x: re.split('[#  @ ]', x))})
dd.head()    
s = dd['col'].str[:]
dd= pd.DataFrame(s.values.tolist())
dd.head()

cols = range(len(list(dd)))
num_cols = len(list(dd))
new_cols = ['col' + str(i) for i in cols]
dd.columns = new_cols[:num_cols]

请记住,数据量巨大……2,000万。无法执行任何循环操作。

预先感谢

2 个答案:

答案 0 :(得分:4)

您可以使用Series.str.findall提取分隔符之间长度为4的整数:

#https://stackoverflow.com/a/55096994/2901002
s = df['code'].str.findall(r'(?<![^#])\d{4}(?![^@])')
#alternative
#s = df['code'].str.replace('[#@]', ' ').str.findall(r'(?<!\S)\d{4}(?!\S)')

然后使用numpy.repeatchain.from_iterable通过str.len创建新的DataFrame:

from itertools import chain

df = pd.DataFrame({
    'id' : df['id'].values.repeat(s.str.len()),
    'new_code' : list(chain.from_iterable(s.tolist()))
})
print (df)
    id new_code
0    1     1759
1    1     1362
2    1     1094
3    1     1356
4    2     1354
5    2     1101
6    2     1108
7    5     1430
8    5     1431
9    5     1074
10   5     1109
11   2     1809
12   2     1816
13   2     1076

答案 1 :(得分:2)

使用Series.str.extractall和其他正则表达式模式的另一种方法:

(df.set_index('id').code.str.extractall(r'(?:[^\.]|^)(?P<new_code>\d{4})')
 .reset_index(0)
 .reset_index(drop=True)
)

[出]

    id new_code
0    1     1759
1    1     1362
2    1     1094
3    1     1356
4    2     1354
5    2     1101
6    2     1108
7    5     1430
8    5     1431
9    5     1074
10   5     1109
11   2     1809
12   2     1816
13   2     1076
14   2     1110