【问题标题】:How to locate multiple returned values from a function into multiple columns of pandas dataframe?如何将函数的多个返回值定位到熊猫数据框的多列中?
【发布时间】:2019-11-14 21:22:51
【问题描述】:

我有一个函数来计算最大频率项及其速率,我想将这些值设置为 数据框中两个不同列的 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)

我还检查了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')

【问题讨论】:

  • 为什么最后一列的费率为 0.5?那不应该是1吗?
  • 可能,首先,您不应该将数字列表存储在 pandas 数据框中,四个目的和目的,这是低效的。对Idrow in Id 使用多级索引或两列。
  • @thushv89 你是对的,它是 (1.0),很抱歉造成混淆。
  • @MaxNoe 该列表是之前操作的输出,数字用于说明,您能否举例说明您的想法。

标签: python pandas dataframe


【解决方案1】:

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

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

请看下面的代码。

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])})

【讨论】:

  • 我的问题是如何在df中的NaN值中定位函数的返回值,如果我是对的,你的方式似乎是在df中创建新列,填充NaN的条件在哪里?
猜你喜欢
  • 2014-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-13
  • 2014-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多