gpt4 book ai didi

python - 是否有更好的矢量化解决方案来使用在第二个数据帧中定义为变量的索引和列写入数据帧?

转载 作者:行者123 更新时间:2023-12-04 07:23:09 27 4
gpt4 key购买 nike

我有一个基本数据框,然后我想填充某些索引和列,这些索引和列由第二个数据框定义,我想影响基本 df 中的更改。第二个数据帧的索引 df_idx 是我感兴趣的 base_df 行; df_idx 还包含要填充的开始列和结束列,以及要写入的值。
base_df 看起来像这样:

import pandas as pd
import numpy as np

months = list(range(1, 13))
li = list(map(str, months))
cols = ['ID']
cols.extend(li)

df_base = pd.DataFrame(np.random.randint(0,1000,size=(5, 13)), columns=cols)
df_base.loc[[1,2],'1':'12'] = np.nan
df_base.loc[4,'7':'12'] = np.nan

ID 1 2 3 4 5 6 7 8 9 10 11 12
0 328 45.0 226.0 388.0 286.0 557.0 930.0 234.0 418.0 863.0 500.0 232.0 116.0
1 340 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 865 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 293 772.0 185.0 6.0 284.0 522.0 826.0 995.0 370.0 87.0 668.0 469.0 40.0
4 313 947.0 272.0 936.0 501.0 241.0 731.0 NaN NaN NaN NaN NaN NaN

下面的 df_idx 显示,对于索引 1,val 210 将沿 base_df 中从列 '1' 到列 '12' 的行填充:
df_idx = pd.DataFrame({'start': [1, 2, 3],
'end': [12, 10, 11],
'val':np.random.randint(0,1000,size=(1, 3))[0]},
index=[1,2,4])

start end val
1 1 12 210
2 2 10 663
4 3 11 922
我可以遍历行,我不想这样做,特别是因为 base_df 可能是 >250,000 行,如下所示:
for idx, row in df_idx.iterrows():
mntStrt = str(row['start'])
mnthEnd = str(row['end'])
df_base.loc[idx, mntStrt:mnthEnd] = row['val']
或者我现在倾向于使用 pandas 应用功能:
def inputVals(x):
idx = x.name
mntStrt = str(x['start'])
mnthEnd = str(x['end'])
df_base.loc[idx, mntStrt:mnthEnd] = x['val']

df_idx.apply(lambda x: inputVals(x), axis=1)
生成的数据框如下所示:
    ID  1   2   3   4   5   6   7   8   9   10  11  12
0 947 537.0 827.0 477.0 39.0 586.0 370.0 576.0 556.0 119.0 158.0 990.0 958.0
1 157 129.0 129.0 129.0 129.0 129.0 129.0 129.0 129.0 129.0 129.0 129.0 129.0
2 545 NaN 849.0 849.0 849.0 849.0 849.0 849.0 849.0 849.0 849.0 NaN NaN
3 549 835.0 205.0 158.0 499.0 451.0 887.0 145.0 6.0 518.0 385.0 34.0 613.0
4 57 673.0 55.0 925.0 925.0 925.0 925.0 925.0 925.0 925.0 925.0 925.0 NaN
我觉得有一种更有效的方法来解决这个问题;任何见解或批评都将受到欢迎。谢谢!

最佳答案

一种方法是 reshape df_idx 以在索引为 df_idx 的数据帧中的正确位置以及所需列 1 到 12 中获取新值。为此,您可以使用 numpy 并将列开始和结束进行比较为 1 到 12。相乘通过 val 列并根据需要设置索引列。所以

# set sedd for reproductibility with df_idx
np.random.seed(1)

tmp = \
pd.DataFrame(
data = ((df_idx['start'].to_numpy()[:, None] <= np.arange(1,13))
& (df_idx['end'].to_numpy()[:, None] >= np.arange(1,13)))
*df_idx['val'].to_numpy()[:, None],
index=df_idx.index,
columns=li
).replace(0,np.nan) #

print(tmp)
1 2 3 4 5 6 7 8 9 10 11 12
1 37.0 37.0 37 37 37 37 37 37 37 37 37.0 37.0
2 NaN 235.0 235 235 235 235 235 235 235 235 NaN NaN
4 NaN NaN 908 908 908 908 908 908 908 908 908.0 NaN
现在您可以使用 update 在 df_base 中设置新值
df_base.update(tmp, overwrite=True) # no need of reassignment with update 
# set overwrite = False if you only change the nan values in df_base to be updated
print(df_base)
ID 1 2 3 4 5 6 7 8 9 10 \
0 72 767.0 905.0 715.0 645.0 847.0 960.0 144.0 129.0 972.0 583.0
1 390 37.0 37.0 37.0 37.0 37.0 37.0 37.0 37.0 37.0 37.0
2 398 NaN 235.0 235.0 235.0 235.0 235.0 235.0 235.0 235.0 235.0
3 319 829.0 534.0 313.0 513.0 896.0 316.0 209.0 264.0 728.0 653.0
4 633 456.0 542.0 908.0 908.0 908.0 908.0 908.0 908.0 908.0 908.0

11 12
0 749.0 508.0
1 37.0 37.0
2 NaN NaN
3 627.0 431.0
4 908.0 NaN

关于python - 是否有更好的矢量化解决方案来使用在第二个数据帧中定义为变量的索引和列写入数据帧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68377621/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com