我需要比较同一数据框中的列并对其进行排名

时间:2018-11-20 10:51:57

标签: python pandas numpy

我有一个包含6列的数据框,我需要将每3列与其他3列进行比较。 6列是相同的数据,但前3列的值来自一种方法,其他三列的值来自其他方法。所以我需要比较它们的差异或差异。

Df.head()

  A    B    C  A-1  B-1  C-1
190  289  300  190  287  267

我的条件是

conditions = [(combined_min['A'] == combined_min['A-1']) & (combined_min['B'] == combined_min['B-1'] & combined_min['C'] == combined_min['C-1']),
              (combined_min['A'] > combined_min['A-1']) & (combined_min['B'] > combined_min['B-1'] & combined_min['C'] > combined_min['C-1']),
              (combined_min['A'] < combined_min['A-1']) & (combined_min['B'] < combined_min['B-1'] & combined_min['C'] < combined_min['C-1'])]

我的选择是

choices     = [ "same", 'kj_greater', 'mi_greater' ]

然后我尝试了

combined_min['que'] = np.select(conditions,choices, default=np.nan)

但是它会抛出错误消息,

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

最后,我需要一个这样的数据框,

  A    B    C  A-1  B-1  C-1         que
190  289  300  190  287  267  kj_greater

如果A,B和C列的值高于kj_greater,否则为mi_greater,如果所有6个都相同,则相同。

3 个答案:

答案 0 :(得分:2)

编辑

经过一番挖掘/反思,我意识到我错了:事实证明& 在熊猫中是逻辑运算符。 &pd.Seriespd.DataFrame对象之间实现成对逻辑。不幸的是,&的运算符优先级与and不同,因此您必须小心(在这种情况下,&的优先级比==,{{1} }或>)。 OP代码中的错误归结为在正确的位置缺少括号。

因此,要获得OP最初使用的标签类型,代码应为:

<

这将输出:

import numpy as np
import pandas as pd

data= [
    [191, 289, 300, 190, 287, 267],
    [191, 289, 300, 200, 312, 400],
    [191, 289, 300, 191, 289, 300],
    [191, 289, 300, 200, 287, 400],
]
combined_min = pd.DataFrame(data=data, columns=['A', 'B','C','A-1','B-1','C-1'])

cond = lambda x: [(x['A'] == x['A-1']) & (x['B'] == x['B-1']) & (x['C'] == x['C-1']),
                  (x['A'] > x['A-1'])  & (x['B'] > x['B-1'])  & (x['C'] > x['C-1']),
                  (x['A'] < x['A-1'])  & (x['B'] < x['B-1'])  & (x['C'] < x['C-1'])]
choices = ['same', 'kj_greater', 'mi_greater']

combined_min['que'] = np.select(cond(combined_min), choices, default=np.nan)
print(combined_min)

(可选) A B C A-1 B-1 C-1 que 0 191 289 300 190 287 267 kj_greater 1 191 289 300 200 312 400 mi_greater 2 191 289 300 191 289 300 same 3 191 289 300 200 287 400 nan 可以简化为一种形式:

cond

尽管这会在一定程度上降低可读性。

答案 1 :(得分:1)

您的情况有误。问题在于您不是在直接比较布尔值,而是一组包含布尔值的pd.Series,它们不会像您那样直接进行比较。

所以:

df['A'] == df['A-1']

返回:

0    True
dtype: bool

因此,当您这样做时:

df['A'] == df['A-1'] & df['A'] == df['A-1']

您收到提到的错误。尝试使用括号将每个术语分开,然后使用any()从pd.Series中获取布尔值:

((df['A'] == df['A-1']) & (df['A'] == df['A-1'])).any()

答案 2 :(得分:1)

问题是您在条件上缺少括号。每个条件都必须用括号括起来。

conditions = [(combined_min['A'] == combined_min['A-1']) & (combined_min['B'] == combined_min['B-1']) & (combined_min['C'] == combined_min['C-1']),
          (combined_min['A'] > combined_min['A-1']) & (combined_min['B'] > combined_min['B-1']) & (combined_min['C'] > combined_min['C-1']),
          (combined_min['A'] < combined_min['A-1']) & (combined_min['B'] < combined_min['B-1']) & (combined_min['C'] < combined_min['C-1'])]