Pandas DataFrame - 根据其他列赋值1和0

3

我有一个包含国家名称和能源输出百分比的数据框。我需要添加一列新的数据,根据国家的能源输出是否高于或低于能源输出中位数来分配1或0。一些示例代码如下:

import pandas as pd
def answer():
    df = pd.DataFrame({'name':['china', 'america', 'canada'], 'output': [33.2, 15.0, 5.0]})
    df['newcol'] = df.where(df['output'] > df['output'].median(), 1, 0)
    return df['newcol']
answer()

这段代码返回了以下错误信息:

ValueError: Wrong number of items passed 2, placement implies 1

我感觉这只需要一个非常简单的修复,但是我刚接触 Pandas。请帮我结束我的挫败感。

2个回答

6

@Vaishali解释了为什么pd.DataFrame.where没有按你预期的工作,并建议你使用np.where,这是非常好的建议。

我建议您可以直接将布尔结果转换为整数。

安装

df = pd.DataFrame({
    'name':['china', 'america', 'canada'],
    'output': [33.2, 15.0, 5.0]
})

Option 1
选项一
df['newcol'] = (df['output'] > df['output'].median()).astype(int)

选项2
或者更快地使用底层的numpy数组
o = df['output'].values
df['newcol'] = (o > np.median(o)).astype(int)

非常感谢!我尝试了布尔掩码,但是在重新格式化返回的True|False值时遇到了困难。我对Pandas非常陌生,学习所有文档都很困难。你和@Vaishali提供的信息非常有帮助 :) - Silent-J

2

您不需要使用循环,因为解决方案是矢量化的。

df['newcol'] = np.where((df['output'] > df['output'].median()), 1, 0)

    name    output  newcol
0   china   33.2    1
1   america 15.0    0
2   canada  5.0     0

对于错误的传递数量,df.where与np.where有些不同。它返回一个与self相同形状的对象,其中对应条目来自cond为True的self,否则来自other。因此,在您的情况下,它返回一个具有两列而不是系列的数据框,因此当您尝试将该数据框分配给系列时,会收到错误消息。


我一直在想为什么其他帖子要使用np.where!所以本质上,我所做的是将整个df传递到我的新系列中,这就是为什么它会抛出错误的原因? - Silent-J
np.where在if-else场景中非常有用,当您需要输出为布尔类型以外的任何数据类型时。即使对于布尔类型,它也可以工作,但布尔掩码更好。是的,您将一个df传递到新系列中,因此出现了错误。您可以通过简单地打印df.where(df['output']> df['output'].median(), 1, 0)来查看发生了什么。 - Vaishali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接