如何在不丢失数据点顺序的情况下将 Pandas 中的字符串列表分解为单个列表
Posted
技术标签:
【中文标题】如何在不丢失数据点顺序的情况下将 Pandas 中的字符串列表分解为单个列表【英文标题】:How to explode list of strings in Pandas to a single list without losing the order of data points 【发布时间】:2021-01-27 17:25:52 【问题描述】:我将一些整数值存储为 Redshift 中的字符串列表(Varchar 类型),因为 Redshift 不支持 list [] data-types 。现在出于某种分析目的,我需要将字符串列表(包含整数值)转换为一维 int 数组。
样本数据:
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-column 是一个字符串列表
【问题讨论】:
【参考方案1】:试试下面的代码(希望是不言自明的):
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]]
【讨论】:
【参考方案2】:一种缓慢应用的方法是将这些字符串评估为列表,然后求和。
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 稍微快一点,但可惜应用速度很慢。但正如您所看到的,即使是内置的 pandas 字符串方法对于字符串/对象操作也相当慢。至少它的代码略少:D以上是关于如何在不丢失数据点顺序的情况下将 Pandas 中的字符串列表分解为单个列表的主要内容,如果未能解决你的问题,请参考以下文章
如何在不丢失 Xampp 中的数据的情况下将类型从 varchar 更改为 Date
如何在不丢失 exif 数据的情况下将 UIImage 转换为 JPEG?