Мне нужно сравнить столбцы в одном и том же кадре данных и ранжировать их - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть фрейм данных с 6 столбцами, мне нужно сравнить каждые 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 голосов
/ 20 ноября 2018

Ваша ошибка в ваших условиях.Проблема в том, что вы сравниваете не логическое значение напрямую, а набор 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()
0 голосов
/ 20 ноября 2018

Проблема в том, что вам не хватает скобок в условиях.Каждое условие должно быть заключено в круглые скобки.

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'])]
0 голосов
/ 20 ноября 2018

Редактировать

После небольшого копания / размышления я понял, что был неправ: оказывается, & - это логический оператор в Пандах.& реализует попарно логические и между pd.Series и pd.DataFrame объекты.К сожалению, & имеет приоритет оператора, отличный от and, поэтому вы должны быть осторожны с ним (в этом случае & имеет более высокий приоритет, чем ==, > или <).Ошибка в коде 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 можно свести к одной строке:

from functools import reduce
from operator import eq, gt, lt, and_

cond = lambda x: [reduce(and_, (op(x[c], x['{}-1'.format(c)]) for c in 'ABC')) for op in (eq, gt, lt)]

Хотя это несколько снижает читабельность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...