我有一个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
通过“序列-列表-NP”数组-“列表-系列”的转换比使用“应用”要快得多。 Apply绝对是较短的代码,可能更容易理解。
增加行数或数组长度将使次数增加相同的幅度。
答案 0 :(得分:2)
最简单的方法是将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]))