【问题标题】:Update cell values where data is missing using function row-by-row使用函数逐行更新数据丢失的单元格值
【发布时间】:2019-05-31 06:11:08
【问题描述】:

假设我有一个看起来像这样的 DataFrame:

In [1]: df = pd.DataFrame([['name1', 2, 3, 'red'], ['name2', 4, 5, 'orange'], ['name3', 6, 7, '-'], ['name4', 8, 9, '-']], \
              columns=('names', 'data1', 'data2', 'category'))
        df

Out[1]:
     name   data1   data2   category
0   name1       2       3        red
1   name2       4       5     orange
2   name3       6       7          -
3   name4       8       9          -

对于某些行,某些列中缺少数据,用“-”表示:

我要做的是逐行填写缺失的数据。如果将名称传递给它,则有一个函数可以识别每一行的正确类别。我使用了任意术语来保持问题的一般性和广泛性,因为实际函数从数据库中提取数据。例如:

In [2]: import library as lib
        lib.get_category('name1')

Out[2]: ['red']

如何使用函数逐行更新所有缺失值?我尝试使用 df.loc 来获取所有缺少数据的行并将一系列相应的名称传递给函数,但它只会使用该系列中的最后一个值更新任何缺失值。我相信这里的核心问题是正确迭代。

最终的预期输出应如下所示(假设 lib.get_category('name3') 返回 ['yellow'] 并且 lib.get_category('name4') 返回 ['green']):

Out[1]:
     name   data1   data2   category
0   name1       2       3        red
1   name2       4       5      orange
2   name3       6       7      yellow
3   name4       8       9       green

【问题讨论】:

  • 最终的预期输出是什么?是否有您引用的字典(也发布相同的内容)谢谢
  • @anky_91 我添加了预期的输出。这是 DataFrame 的字典: data = {'name': ['name1', 'name2', 'name3', 'name4'], 'data1': [2, 4, 6, 8], 'data2' : [3, 5, 7, 9], 'category': ['red', 'orange', '-', '-']} 这是你要求的吗?
  • 没错,我可以提供帮助,但您需要为此准备一个映射字典。 apply() 工作吗?通过映射字典我的意思是{'name1': 'red', 'name2': 'orange', 'name3': 'yellow', 'name4': 'green'}
  • apply() 非常接近我想要的。通过使用 Mohit 的方法并稍微修改它以使用 try/except 在函数没有返回任何内容的情况下,我能够为每一行获得唯一的输出。理想情况下,我希望它跳过已经包含数据的所有内容,这样我就不会意外修改已经存在的数据(并获得更好的性能)。所以在我的例子中,前两行将被跳过,函数将在最后两行上运行。
  • 只要我设置df['category'] = df.category.replace('-',np.nan).fillna(df['name'].apply(func)),这似乎确实有效。一个我没想到的有趣的解决方法,谢谢!

标签: python pandas dataframe iteration


【解决方案1】:

使用可以使用Series.apply

import library as lib
def func(name):
    return lib.get_category('name1')

df['category'] = df['name'].apply(func)

apply 函数func 将从名称列中获取值并返回对应行的值。所以相应地编辑你的函数。

还要注意,上面的代码将替换列的现有类别值。但是正如您提到的,类别可以从名称中派生出来,那么这应该不是问题。

【讨论】:

    【解决方案2】:

    试试这个:

    df.loc[df.category.astype('str')=='-','category']=df[df.category.astype('str')=='-']['names'].apply(lib.get_category)
    

    只需将 apply 函数与 loc 一起使用即可找到需要应用的行。

    【讨论】:

    • 这似乎是我需要的。有没有办法使用这种方法将更多参数传递给 get_category 函数?我遇到了错误,可能是因为我没有为函数提供它所需要的一切。假设get_category 函数除了该行的名称字符串之外还需要第二个参数“名称”(指示传入的数据类型),那么这种方法是否仍然有效?例如lib.get_category('name1', 'name')
    • @AlexW 如果您需要更多参数,那么只需将其与列名一起传递即可。
    猜你喜欢
    • 2017-07-18
    • 2011-08-19
    • 2020-11-28
    • 1970-01-01
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多