用数据框对应元素的列表函数替换列中某行的值

1 投票
1 回答
33 浏览
提问于 2025-04-14 16:21

我有一个用户定义的函数(叫做 f),它是一个列表的函数。比如说,这个函数可以是计算列表中所有元素的和,但也可以是其他的函数。

接下来,我有一个数据表(dataframe),里面有两列:'pred' 列包含了一些数字的列表,而 'value' 列则包含一个单独的数字。这里的 -1 是一个占位符,需要被更新。

import pandas as pd

def f(my_list):
    return sum(my_list)

data = {'pred':[[],[1],[1],[1],[2],[2,3],[2,4],[3],[3,4],[4],[6,7,9,10]]}

df = pd.DataFrame(data)
df.index = df.index + 1

df.loc[5,'value'] = 1
df.loc[8,'value'] = 0
df.loc[10,'value'] = 2
df.loc[11,'value'] = 100
df.value = df.value.fillna(-1).astype(int) #placeholder, the values cannot be negative

print(df)
             pred  value
1              []     -1
2             [1]     -1
3             [1]     -1
4             [1]     -1
5             [2]      1
6          [2, 3]     -1
7          [2, 4]     -1
8             [3]      0
9          [3, 4]     -1
10            [4]      2
11  [6, 7, 9, 10]    100

现在,我需要反向遍历这个数据表的每一行,把 -1 的值更新为那些在 'pred' 列中包含当前行的 'i' 的值的列表应用函数 f 后的结果。可以保证,在第 1 行到第 i 行的 'pred' 列中不会出现 'i'。

在这个例子中,我们应该得到:

value in row 9: f([100]) = 100;
value in row 7: f([100]) = 100;
value in row 6: f([100]) = 100;
value in row 4: f([2, 100, 100]) = 202;
value in row 3: f([100, 0, 100]) = 200;
value in row 2: f([1, 100, 100]) = 201;
value in row 1: f([201, 200, 202]) = 603.

所以,我需要帮助来写一个循环来完成这个任务。

for i in range(len(df),0,-1):
  if df.loc[i,'value'] == -1:
    df.loc[i,'value'] = ???

任何建议都非常感谢。

1 个回答

2

如果我理解正确,你可以创建一个字典,这个字典里存的是被其他索引引用的索引。然后你可以反向遍历那些-1的索引,并根据这些索引找到相关的行,然后把这些行传递给f函数:

s = df['pred'].explode()
dic = s.index.groupby(s)
# {1: [2, 3, 4], 2: [5, 6, 7], 3: [6, 8, 9], ...}

for i in df.index[df['value'].eq(-1)][::-1]:
    df.loc[i, 'value'] = f(df.loc[dic.get(i, []), 'value'])

更新后的数据表:

             pred  value
1              []    603
2             [1]    201
3             [1]    200
4             [1]    202
5             [2]      1
6          [2, 3]    100
7          [2, 4]    100
8             [3]      0
9          [3, 4]    100
10            [4]      2
11  [6, 7, 9, 10]    100

接下来,我们一步一步分析这个循环,它的作用是:

df.loc[9, 'value'] = f(df.loc[[11], 'value'])       # f([100])
df.loc[7, 'value'] = f(df.loc[[11], 'value'])       # f([100])
df.loc[6, 'value'] = f(df.loc[[11], 'value'])       # f([100])
df.loc[4, 'value'] = f(df.loc[[7, 9, 10], 'value']) # f([100, 100, 2])
df.loc[3, 'value'] = f(df.loc[[6, 8, 9], 'value'])  # f([100, 0, 100])
df.loc[2, 'value'] = f(df.loc[[5, 6, 7], 'value'])  # f([1, 100, 100])
df.loc[1, 'value'] = f(df.loc[[2, 3, 4], 'value'])  # f([201, 200, 202])

撰写回答