如何将函数的多个返回值定位到dataframe的多个列中?

2024-09-28 05:24:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个函数来计算最大频率项目和它的速率,我想设置这些值 一个数据帧中两个不同列的值: (注意:每列都有其他值(非值),我要填充na)

  Id    numbers     max_frq    rate
   1   1,1,1,2,3     NaN       NaN
   2   1,6,6,6       NaN       NaN
   3   7,7           NaN       NaN 

期望值:

  id    numbers     max_frq    rate
   1   1,1,1,2,3      1       0.6
   2   1,6,6,6        6       0.75
   3   7,7            7       1.0

这是我的代码,它用重复的值(max\u no的第一个值,rate的第一个值)填充列中的所有NaN值。 如何用其相关值填充每个Id行?你知道吗

def max_rate(Id) # Id is a list 
    num = pd.Series(numbers).value_counts()
    max_no = num.max()
    sum_no = num.sum()
    rate = max_no / sum_no
    return max_no, rate_no

for Id in (df["Id"].unique()):
    max_no, rate_no = max_rate(Id)
    df.max_frq = df.max_frq.fillna(max_no)
    df.rate = df.rate.fillna(rate_no)

我还检查了this similar question,但我不明白如何使用lambdaseries以及将(fillna)条件放在何处,我将其编码

for Id in (df["Id"].unique()):
    g = lambda x: pd.Series(max_rate(x))
    df[['max_frq', 'rate']] = df.apply(g, axis=1)

获取错误: ('包含多个元素的数组的真值不明确。使用a.any()或a.all()','发生在索引50')


Tags: noiniddfforratenannum
1条回答
网友
1楼 · 发布于 2024-09-28 05:24:38

要解决您的问题,您需要为每一行:

  • 在数字列表中查找最常用的值
  • 找出所有事件中最常见的部分
  • 将结果存储在两个新列中

请看下面的代码。你知道吗

from collections import Counter


def max_rate(values):
    most_common, num_most_common = Counter(values).most_common(1)[0]
    return most_common, num_most_common / len(values)

df = pd.DataFrame({'numbers': [[1, 1, 1, 2, 3], 
                               [1, 6, 6, 6], 
                               [7, 7]]})

df[['most_common', 'rate']] = pd.DataFrame(df['numbers'].apply(max_rate).tolist())
print(df)

结果:

           numbers  most_common  rate
0  [1, 1, 1, 2, 3]            1  0.60
1     [1, 6, 6, 6]            6  0.75
2           [7, 7]            7  1.00

如果您不想使用计数器您可以实现如下最大速率函数

def max_rate(values):
    most_common_value = max(values, key=values.count)
    return most_common_value, values.count(most_common_value) / len(values)

编辑: 如果要显式创建包含已包含NaN值的列的数据帧,可以执行以下操作:

import pandas as pd
import numpy as np

df = pd.DataFrame({'numbers': [[1, 1, 1, 2, 3], [1, 6, 6, 6], [7, 7]]})
df['most_common'] = np.nan
df['rate'] = np.nan

result = df['numbers'].apply(max_rate)
for i, (most_common, rate) in zip(df.index, result):
    df.at[i, 'most_common'] = most_common
    df.at[i, 'rate'] = rate

在该解决方案中,您可以遍历数据并使用收到的结果逐行更新它。但是,我更喜欢前面的方法,即从获得的结果创建新列。你知道吗

编辑2:

如果您一定要使用fillna您可以尝试以下方法,但是,在我看来,它仍然是围绕第一个解决方案。你知道吗

df = pd.DataFrame({'numbers': [[1, 1, 1, 2, 3], [1, 6, 6, 6], [7, 7]]})
df['most_common'] = np.nan
df['rate'] = np.nan

result = df['numbers'].apply(max_rate)

df = df.fillna({'most_common': pd.Series([elem[0] for elem in result]),
                'rate': pd.Series([elem[1] for elem in result])})

相关问题 更多 >

    热门问题