Python 如何在不丢失数据点顺序的情况下将Pandas中的字符串列表分解为单个列表
我将一些整数值存储为Redshift中的字符串列表Varchar type,因为Redshift不支持list[]数据类型。现在出于某种分析目的,我需要将包含整数值的字符串列表转换为一维整数数组 样本数据: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(
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