У меня есть фрейм данных pandas с 4 столбцами. так
ID col1 col2 col3
1 Strongly Positive Strongly Positive Weekly Positive
2 Strongly Positive Strongly Positive Neutral
3 Strongly Negative Strongly Negative Weekly Negative
4 Weekly Negative Strongly Negative Neutral
5 Neutral Neutral Neutral
6 Strongly Positive Strongly Negative Strongly Negative
7 Strongly Negative Weekly Positive Neutral
8 Neutral Weekly Negative Weekly Positive
Каждый из столбцов может принимать такие значения, как (сильно положительные, недельные положительные, нейтральные, еженедельные отрицательные и сильно отрицательные, а также столбец идентификаторов. Мне нужно создать новый столбец с этой логикой
Мне нужно, чтобы окончательный фрейм данных был таким
ID col1 col2 col3 Aggregated_Col
1 Strongly Positive Strongly Positive Weekly Positive Positive
2 Strongly Positive Strongly Positive Neutral Positive
3 Strongly Negative Strongly Negative Weekly Negative Negative
4 Weekly Negative Strongly Negative Neutral Negative
5 Neutral Neutral Neutral Neutral
6 Strongly Positive Strongly Negative Strongly Negative Both
7 Strongly Negative Weekly Positive Neutral Both
8 Neutral Weekly Negative Weekly Positive Both
Не в состоянии придумать логику
ID col1 col2 col3 Aggregated_Col
1 Strongly Positive Strongly Positive Weekly Positive Positive
2 Strongly Positive Strongly Positive Neutral Positive
3 Strongly Negative Strongly Negative Weekly Negative Negative
4 Weekly Negative Strongly Negative Neutral Negative
5 Neutral Neutral Neutral Neutral
6 Strongly Positive Strongly Negative Strongly Negative Both
7 Strongly Negative Weekly Positive Neutral Both
8 Neutral Weekly Negative Weekly Positive Both
Я предлагаю перекодировать эти значения в целые числа, например.
recode = {"Strongly Positive": 2, "Weakly Positive": 1, "Neutral": 0, "Weakly Negative": -1, "Strongly Negative": -2}
Затем вы можете написать такую функцию:
def interpret(values):
if min(values) >= 0:
return 1
elif ...
и вызвать его с помощью df.apply(interpret, axis=1)
У вас есть 3 столбца, поэтому вы можете использовать
DF.apply(YourCustomFunction, axis=1)
Ось 1 сообщает, что вы хотите выполнить операцию над строками. Напишите свою пользовательскую логику в виде функции:
def MyFunction(x):
if condition1:
Do something
elif condition2:
Do something
........
Так проходит
DF['NewCol'] = DF.apply(MyFunction, axis=1)
Будет делать свое дело. Имейте в виду, что x, переданный функции, будет массивом, поэтому вы должны правильно адресовать его, индексируя в своей функции.
Вы можете замаскировать соответствующие элементы следующим образом:
# set index as ID:
df.set_index('ID', inplace=True)
has_pos = df.apply(lambda x: x.str.contains('Positive')).any(axis=1)
has_neg = df.apply(lambda x: x.str.contains('Negative')).any(axis=1)
has_both = has_pos & has_neg
# update
df['Agg_Col'] = 'Neutral'
df.loc[has_pos,'Agg_Col'] = 'Positive'
df.loc[has_neg,'Agg_Col'] = 'Negative'
df.loc[has_both,'Agg_Col'] = 'Both'
from numpy.core.defchararray import find
a = df.to_numpy().astype(str)
b = np.select([find(a, 'Pos') >= 0, find(a, 'Neg') >= 0], [1, -1], 0)
c = np.select(
[(b == 0).all(1), (b >=0).all(1), (b <= 0).all(1)],
['Neutral', 'Positive', 'Negative'],
'Both'
)
df.assign(Agg=c)
col1 col2 col3 Agg
ID
1 Strongly Positive Strongly Positive Weekly Positive Positive
2 Strongly Positive Strongly Positive Neutral Positive
3 Strongly Negative Strongly Negative Weekly Negative Negative
4 Weekly Negative Strongly Negative Neutral Negative
5 Neutral Neutral Neutral Neutral
6 Strongly Positive Strongly Negative Strongly Negative Both
7 Strongly Negative Weekly Positive Neutral Both
8 Neutral Weekly Negative Weekly Positive Both
from numpy.core.defchararray import find
a = df.to_numpy().astype(str)
b = np.select([find(a, 'Pos') >= 0, find(a, 'Neg') >= 0], [1, -1], 0)
m = {
(0, 0): 'Neutral', (1, -1): 'Both',
(1, 1): 'Positive', (1, 0): 'Positive',
(-1, -1): 'Negative', (0, -1): 'Negative',
}
df.assign(Agg=[*map(m.get, zip(b.max(1), b.min(1)))])
col1 col2 col3 Agg
ID
1 Strongly Positive Strongly Positive Weekly Positive Positive
2 Strongly Positive Strongly Positive Neutral Positive
3 Strongly Negative Strongly Negative Weekly Negative Negative
4 Weekly Negative Strongly Negative Neutral Negative
5 Neutral Neutral Neutral Neutral
6 Strongly Positive Strongly Negative Strongly Negative Both
7 Strongly Negative Weekly Positive Neutral Both
8 Neutral Weekly Negative Weekly Positive Both
Нет, просто используйте df.values
.
Я столкнулся с проблемой в df.to_numpy(). Поэтому панды должны быть обновлены до 0.24 или выше.