【发布时间】:2019-03-05 20:43:18
【问题描述】:
我有一个 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 绝对是更短的代码并且可能更容易理解。
增加行数或数组长度会增加同样数量的次数。
【问题讨论】:
标签: python pandas numpy series