【问题标题】:Column level parsing in pandas data frame熊猫数据框中的列级解析
【发布时间】:2019-08-01 10:33:19
【问题描述】:

目前我正在处理 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]

请记住数据的大小是巨大的......2000万。不能做任何循环。

提前致谢

【问题讨论】:

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


    【解决方案1】:

    您可以使用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.repeatstr.len 创建新的DataFrame 并通过chain.from_iterable 展平:

    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 df = pd.DataFrame({ ----> 2 'id' 中出现此错误 TypeError Traceback (最近一次调用最后一次) df['id'].values.repeat(s.str.len()), 3 'new_code' : list(chain.from_iterable(s.tolist())) 4 }) 5 TypeError: Cannot cast array data from dtype ('float64') 到 dtype('int64') 根据规则 'safe'
    • @NikitaAgarwal - 如何将s.str.len() 更改为s.str.len().astype(np.int64)
    • 我没有改变任何东西..我的代码如下 - df = pd.DataFrame({ 'id' : df['id'].values.repeat(s.str.len() ), 'new_code' : list(chain.from_iterable(s.tolist())) }) df.head(20) 目前我正在处理完整的数据集...这是一个原因吗?有些值的格式不同
    • 如果使用df = pd.DataFrame({ 'id' : df['id'].values.repeat(s.str.len().astype(np.int64)), 'new_code' : list(chain.from_iterable(s.tolist())) })也会出现同样的错误?
    • @NikitaAgarwal - 如果我的回答有帮助,请不要忘记accept。谢谢。
    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2021-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-10
      • 2018-04-25
      • 2013-04-03
      • 2018-07-31
      • 2019-01-01
      相关资源
      最近更新 更多