Python 如何在不丢失数据点顺序的情况下将Pandas中的字符串列表分解为单个列表

Python 如何在不丢失数据点顺序的情况下将Pandas中的字符串列表分解为单个列表,python,pandas,amazon-redshift,Python,Pandas,Amazon Redshift,我将一些整数值存储为Redshift中的字符串列表Varchar type,因为Redshift不支持list[]数据类型。现在出于某种分析目的,我需要将包含整数值的字符串列表转换为一维整数数组 样本数据: dummy_df = pd.DataFrame({'customer_id':[1,2,3],'values':[['[1]','[1,8]'],['[3,7]','[3]'],'[5]'] }) print(dummy_df) 输出数据: final_df = pd.DataFrame(

我将一些整数值存储为Redshift中的字符串列表Varchar type,因为Redshift不支持list[]数据类型。现在出于某种分析目的,我需要将包含整数值的字符串列表转换为一维整数数组

样本数据:

dummy_df = pd.DataFrame({'customer_id':[1,2,3],'values':[['[1]','[1,8]'],['[3,7]','[3]'],'[5]'] })
print(dummy_df)
输出数据:

final_df = pd.DataFrame({'customer_id':[1,2,3],'values':[[1,1,8],[3,7,3],[5]] })
final_df

注意:DataFrame dummy_df value列是字符串列表

请尝试以下代码:

dummy_df['values'] = (dummy_df['values'].explode()     # flatten the list structure
                          .str.extractall('(\d+)')     # extract the digits
                          .astype(int)                 # convert to int
                          .groupby(level=0).agg(list)  # aggregate the list
                     )

print(dummy_df.to_dict('list'))
输出:

{'customer_id': [1, 2, 3], 'values': [[1, 1, 8], [3, 7, 3], [5]]}

请尝试以下自我解释的代码:

dummy_df['values'] = (dummy_df['values'].explode()     # flatten the list structure
                          .str.extractall('(\d+)')     # extract the digits
                          .astype(int)                 # convert to int
                          .groupby(level=0).agg(list)  # aggregate the list
                     )

print(dummy_df.to_dict('list'))
输出:

{'customer_id': [1, 2, 3], 'values': [[1, 1, 8], [3, 7, 3], [5]]}

缓慢应用的一种方法是将这些字符串求值到列表中,然后求和

import ast

dummy_df['values'] = dummy_df['values'].explode().apply(ast.literal_eval).sum(level=0)

   customer_id     values
0            1  [1, 1, 8]
1            2  [3, 7, 3]
2            3        [5]
无论如何,使用pandas的复杂对象操作的缩放效果相当差@QuangHoang的方法稍微快一点

import perfplot
import pandas as pd
import numpy as np
import ast


def quang(df):
    return (df['values'].explode()              # flatten the list structure
               .str.extractall('(\d+)')         # extract the digits
               .astype(int)                     # convert to int
               .groupby(level=0).agg(list))[0]  # aggregate the list
           
    
def alollz(df):
    return df['values'].explode().apply(ast.literal_eval).sum(level=0)



perfplot.show(
    setup=lambda n: pd.concat([pd.DataFrame({'customer_id':[1,2,3],
                                             'values':[['[1]','[1,8]'], ['[3,7]','[3]'], '[5]']})]*n,
                              ignore_index=True), 
    kernels=[
        lambda df: quang(df),
        lambda df: alollz(df),
    ],
    labels=['str.extract', 'ast.literal_eval'],
    n_range=[2 ** k for k in range(1, 16)],
    equality_check=lambda x,y: x.compare(y).empty,
    xlabel='~len(df)'
)

缓慢应用的一种方法是将这些字符串求值到列表中,然后求和

import ast

dummy_df['values'] = dummy_df['values'].explode().apply(ast.literal_eval).sum(level=0)

   customer_id     values
0            1  [1, 1, 8]
1            2  [3, 7, 3]
2            3        [5]
无论如何,使用pandas的复杂对象操作的缩放效果相当差@QuangHoang的方法稍微快一点

import perfplot
import pandas as pd
import numpy as np
import ast


def quang(df):
    return (df['values'].explode()              # flatten the list structure
               .str.extractall('(\d+)')         # extract the digits
               .astype(int)                     # convert to int
               .groupby(level=0).agg(list))[0]  # aggregate the list
           
    
def alollz(df):
    return df['values'].explode().apply(ast.literal_eval).sum(level=0)



perfplot.show(
    setup=lambda n: pd.concat([pd.DataFrame({'customer_id':[1,2,3],
                                             'values':[['[1]','[1,8]'], ['[3,7]','[3]'], '[5]']})]*n,
                              ignore_index=True), 
    kernels=[
        lambda df: quang(df),
        lambda df: alollz(df),
    ],
    labels=['str.extract', 'ast.literal_eval'],
    n_range=[2 ** k for k in range(1, 16)],
    equality_check=lambda x,y: x.compare(y).empty,
    xlabel='~len(df)'
)

令人惊叹的非常感谢广:太棒了!!!非常感谢广:谢谢@Alollz。。这种方法也非常有效。非常感谢性能基准图:@ashish是的,我希望它会比QuangHoang的稍快一点,但是很慢。但正如您所看到的,即使是内置的字符串方法,对字符串/对象的操作也相当慢。至少代码稍微少一点:Dthanks@Alollz。。这种方法也非常有效。非常感谢性能基准图:@ashish是的,我希望它会比QuangHoang的稍快一点,但是很慢。但正如您所看到的,即使是内置的字符串方法,对字符串/对象的操作也相当慢。至少它的代码稍微少一点:D