Pandas 有效地创建和填充新数据框(?)
Pandas creating and populating a new dataframe efficiently (?)
我正在从头开始创建一个新的 DataFrame,但我不确定我这样做的方式是否是最有效的方式。
我正在创建:
- 列从不在 3070 = 1
- 列偶尔 1100 = 1
- 列频繁 2200 = 1
我还创建了一个新的警察专栏:
- 其中 70 行 = 1 列从不 = 1
- 其中 110 行 = 1 列偶尔 = 1
- 其中 220 行 = 1 列频繁 = 1
代码:
# create dataframes for each column
df1 = pd.concat([pd.DataFrame([1], columns=['NEVER']) for i in range(3070)],
ignore_index=True)
df2 = pd.concat([pd.DataFrame([1], columns=['OCCASIONAL']) for i in range(1100)],
ignore_index=True)
df3 = pd.concat([pd.DataFrame([1], columns=['FREQUENT']) for i in range(2200)],
ignore_index=True)
# combine dataframes into one
frames = [df1, df2, df3]
df = pd.concat(frames)
# reset index
df = df.reset_index(drop=True)
df['POLICE'] = 0.0
# replace police column values
df.loc[0:69,'POLICE']=1.0
df.loc[3071:3180,'POLICE']=1.0
df.loc[5271:5490,'POLICE']=1.0
# convert NaN into 0
values=(0.0)
df = df.fillna(value=values)
我想我已经做到了,但是我的代码需要很长时间才能处理。这是正常现象,因为我正在创建 6000 多行,还是我的代码效率低下?
您可以使用 np.ones()
和 np.zeros
用 1 和 0 填充该列。使用 numpy 可以获得显着的加速。
import pandas as pd
import numpy as np
# create dataframes for each column
df1 = pd.DataFrame(np.ones(3070), columns=['NEVER'])
df2 = pd.DataFrame(np.ones(1100), columns=['OCCASIONAL'])
df3 = pd.DataFrame(np.ones(2200), columns=['FREQUENT'])
# combine dataframes into one
frames = [df1, df2, df3]
df = pd.concat(frames)
# reset index
df = df.reset_index(drop=True)
df['POLICE'] = np.zeros(6370)
# replace police column values
df.loc[0:69,'POLICE']=np.ones(70)
df.loc[3071:3180,'POLICE']=np.ones(110)
df.loc[5271:5490,'POLICE']=np.ones(220)
# convert NaN into 0
values=(0.0)
df = df.fillna(value=values)
在我的机器中-原始代码:
Process finished --- 2.513995409011841 seconds ---
修改后的代码:
Process finished --- 0.0069921016693115234 seconds ---
我建议采用一种效率更高的完全不同的方法。创建数据的二维列表,然后将其整体转换为数据框。
lst = []
for row in range(6370):
lst.append([None, None, None, None])
for col in range(4):
if (col == 0 and row < 3070)\
or (col == 1 and row >= 3070 and row < 1100)\
or (col == 2 and row >= 4170)\
or (col == 3 and row < 70)\
or (col == 3 and row > 3070 and row <= 3180)\
or (col == 3 and row > 5270 and row <= 5490):
lst[row][col] = 1.0
else:
lst[row][col] = 0.0
df = pd.DataFrame(lst)
df.columns = ["NEVER", "OCCASIONAL", "FREQUENT", "POLICE"]
print(df)
这是输出:
我正在从头开始创建一个新的 DataFrame,但我不确定我这样做的方式是否是最有效的方式。
我正在创建:
- 列从不在 3070 = 1
- 列偶尔 1100 = 1
- 列频繁 2200 = 1
我还创建了一个新的警察专栏:
- 其中 70 行 = 1 列从不 = 1
- 其中 110 行 = 1 列偶尔 = 1
- 其中 220 行 = 1 列频繁 = 1
代码:
# create dataframes for each column
df1 = pd.concat([pd.DataFrame([1], columns=['NEVER']) for i in range(3070)],
ignore_index=True)
df2 = pd.concat([pd.DataFrame([1], columns=['OCCASIONAL']) for i in range(1100)],
ignore_index=True)
df3 = pd.concat([pd.DataFrame([1], columns=['FREQUENT']) for i in range(2200)],
ignore_index=True)
# combine dataframes into one
frames = [df1, df2, df3]
df = pd.concat(frames)
# reset index
df = df.reset_index(drop=True)
df['POLICE'] = 0.0
# replace police column values
df.loc[0:69,'POLICE']=1.0
df.loc[3071:3180,'POLICE']=1.0
df.loc[5271:5490,'POLICE']=1.0
# convert NaN into 0
values=(0.0)
df = df.fillna(value=values)
我想我已经做到了,但是我的代码需要很长时间才能处理。这是正常现象,因为我正在创建 6000 多行,还是我的代码效率低下?
您可以使用 np.ones()
和 np.zeros
用 1 和 0 填充该列。使用 numpy 可以获得显着的加速。
import pandas as pd
import numpy as np
# create dataframes for each column
df1 = pd.DataFrame(np.ones(3070), columns=['NEVER'])
df2 = pd.DataFrame(np.ones(1100), columns=['OCCASIONAL'])
df3 = pd.DataFrame(np.ones(2200), columns=['FREQUENT'])
# combine dataframes into one
frames = [df1, df2, df3]
df = pd.concat(frames)
# reset index
df = df.reset_index(drop=True)
df['POLICE'] = np.zeros(6370)
# replace police column values
df.loc[0:69,'POLICE']=np.ones(70)
df.loc[3071:3180,'POLICE']=np.ones(110)
df.loc[5271:5490,'POLICE']=np.ones(220)
# convert NaN into 0
values=(0.0)
df = df.fillna(value=values)
在我的机器中-原始代码:
Process finished --- 2.513995409011841 seconds ---
修改后的代码:
Process finished --- 0.0069921016693115234 seconds ---
我建议采用一种效率更高的完全不同的方法。创建数据的二维列表,然后将其整体转换为数据框。
lst = []
for row in range(6370):
lst.append([None, None, None, None])
for col in range(4):
if (col == 0 and row < 3070)\
or (col == 1 and row >= 3070 and row < 1100)\
or (col == 2 and row >= 4170)\
or (col == 3 and row < 70)\
or (col == 3 and row > 3070 and row <= 3180)\
or (col == 3 and row > 5270 and row <= 5490):
lst[row][col] = 1.0
else:
lst[row][col] = 0.0
df = pd.DataFrame(lst)
df.columns = ["NEVER", "OCCASIONAL", "FREQUENT", "POLICE"]
print(df)
这是输出: