2

我有一个函数来计算最大频率项及其速率,我想在数据帧中两个不同列的 NaN_values 中设置这些值:(注意:每列都有其他值(non_NaN 值),我想填写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_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)

我也检查了这个类似的问题,但我不明白如何使用lambda系列以及在哪里放置(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')

4

1 回答 1

2

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

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

请看下面的代码。

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

如果你不想使用Counter你可以实现如下的 max_rate 函数

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])})
于 2019-11-14T12:41:01.167 回答