python - 如何有效地将数据框中的 pd.Series 列表更改为 np.arrays 的 pd.Series
问题描述
我有一个 PostgreSQL 数据库,其数据类似于:日期、字符变化、字符变化、整数 [] 在整数数组列中存储了一个值列表:1、2、3、4、5 我正在使用 pd.read_sql将数据读入数据帧。
所以我有一个数据框,其中包含一个日期列、几个字符串列,然后是一个包含整数列表的列。
数组值经常在 numpy 数组中用于进行向量数学运算。
在过去,我找不到将列表列转换为 numpy 数组列而不逐行循环和重新创建数据帧的方法。举个例子:
import pandas as pd
import numpy as np
col1 = ['String data'] * 4
col2 = [[1,2,3,4,5]] * 4
d = {'Description': col1, 'Measures':col2}
df = pd.DataFrame(d)
new_df = pd.DataFrame(columns=df.columns)
for i in range(len(df)):
new_df.loc[i, ['Description','Measures']] = [df.at[i,'Description'], np.array(df.at[i,'Measures'])]
print(new_df)
这种循环可能超过几千行。
最近,我发现如果我可以对 Series -> list -> nparray -> list -> Series 进行单行转换并更有效地实现结果。
import pandas as pd
import numpy as np
col1 = ['String data'] * 4
col2 = [[1,2,3,4,5]] * 4
d = {'Description': col1, 'Measures':col2}
df = pd.DataFrame(d)
df['NParray'] = pd.Series(list(np.array(list(np.array(df['Measures'])))))
df.drop(['Measures'], axis=1, inplace=True)
print(df)
print(type(df['NParray'][0]))
我阅读并尝试使用 Series.array 和 Series.to_numpy,但它们并没有真正实现我想要做的事情。
所以,问题是:有没有一种方法可以将 pd.Series 列表转换为 numpy 数组,就像我正在尝试做的那样?有没有更简单的方法可以将这些列表批量转换为 numpy 数组?
我希望像这样简单的东西:
df['NParray'] =np.asarray(df['Measures'])
df['NParray'] =np.array(df['Measures'])
df['NParray'] =df['Measures'].array
df['NParray'] =df['Measures'].to_numpy()
但这些有不同的功能,不适合我的目的。
------------测试后编辑----------------------- -------------
我设置了一个小测试,看看时间和效率的差异是什么:
import pandas as pd
import numpy as np
def get_dataframe():
col1 = ['String data'] * 10000
col2 = [list(range(0,5000))] * 10000
d = {'Description': col1, 'Measures':col2}
df = pd.DataFrame(d)
return(df)
def old_looping(df):
new_df = pd.DataFrame(columns=df.columns)
starttime = pd.datetime.now()
for i in range(len(df)):
new_df.loc[i, ['Description','Measures']] = [df.at[i,'Description'], np.array(df.at[i,'Measures'])]
endtime = pd.datetime.now()
duration = endtime - starttime
print('Looping', duration)
def series_transforms(df):
starttime = pd.datetime.now()
df['NParray'] = pd.Series(list(np.array(list(np.array(df['Measures'])))))
df.drop(['Measures'], axis=1, inplace=True)
endtime = pd.datetime.now()
duration = endtime - starttime
print('Transforms', duration)
def use_apply(df):
starttime = pd.datetime.now()
df['Measures'] = df['Measures'].apply(np.array)
endtime = pd.datetime.now()
duration = endtime - starttime
print('Apply', duration)
def run_test(tests):
for i in range(tests):
construct_df = get_dataframe()
old_looping(construct_df)
for i in range(tests):
construct_df = get_dataframe()
series_transforms(construct_df)
for i in range(tests):
construct_df = get_dataframe()
use_apply(construct_df)
run_test(5)
10,000 行的结果是: 转换 3.945816
转换 3.968821
转换 3.891866
转换 3.859437
转换 3.860590
申请 4.218867
申请 4.015742
申请 4.046986
申请 3.906360
申请 3.890740
循环 27.662418
循环 27.814523
循环 27.298895
循环 27.565626
循环 27.222970
通过 Series-List-NP Array-List-Series 进行转换比使用 Apply 快得可以忽略不计。Apply 绝对是更短的代码并且可能更容易理解。
增加行数或数组长度将使时间增加相同的数量。
解决方案
最简单的可能是使用 apply 转换为 np.array:df['Measures'].apply(np.array)
完整示例:
import pandas as pd
import numpy as np
col1 = ['String data'] * 4
col2 = [[1,2,3,4,5]] * 4
d = {'Description': col1, 'Measures':col2}
df = pd.DataFrame(d)
display(df.Measures)
df['NParray'] = df['Measures'].apply(np.array)
df.drop(['Measures'], axis=1, inplace=True)
print(df)
print(type(df['NParray'][0]))
推荐阅读
- ios - 转移给其他用户后如何开发和发布应用程序
- python - 是否可以在 guvectorize 函数中返回具有未知输出数组形状的数组
- c# - Asp.Net Core API 中的控制器返回类型
- python - 使用 sudo 运行时出现 Twisted DNS 查询错误
- angular - 如何通过全局服务在打字稿文件中使用 TranslateService (ngx-translate)?
- arrays - 有时不能分配给数组,有时可以
- javascript - 如何声明Vue数据类型
- php - 如何递归地从多维表单数组转换为相关的实体对象
- java - 如何检查android Messenger的队列长度
- video - 第一个 CTU 的 HEVC/x265 帧内编码