#python #pandas #list #lambda #filter
Вопрос:
У меня есть фрейм данных pandas, который выглядит так
country region values
A CA [0, 0, 1, .5]
B NE [0, 0, 0, 1]
C CA [1, 1, 1, .5]
D CA [1, 0, 1, .5]
E EE [0, .5, .5, 0]
F NE [0, 1, 1, 1]
G EE [0, 0, 0, 0]
H NE [0, .5, 1, .5]
I EE [nan, 0]
Я хочу узнать, в каких странах есть все 4 значения 1 ,.5, 0 или 3 значения 1, 0, .5 или 2 значения 1, .5 или 0. Значение 1 равно принятому(A), .5 равно частично принятому(PA) и равно не принятому (NA). Например:
country region values #A_all4 #A_any3 #A_any2 #PA_all4 #PA_any3 #PA_any2
A CA [0, 0, 1, .5] 0 0 0 0 0 0
B NE [0, 0, 0, 1] 0 0 0 0 0 0
C CA [1, 1, 1, .5] 0 1 0 0 0 0
D CA [1, 0, 1, .5] 0 0 1 0 0 0
E EE [0, .5, .5, 0] 0 0 1 0 0 0
F NE [0, 1, 1, 1] 0 1 0 0 0 1
G EE [0, 0, 0, 0] 0 0 0 0 0 0
H NE [0, .5, 1, .5] 0 0 0 0 0 1
I EE [nan, 0] 0 0 0 0 0 0
Я хочу сделать это для всех ценностей (Принятых, Частично принятых и Не принятых). У меня просто не было места, чтобы это сделать. пробовал фильтровать с помощью лямбды, но это не дает мне нужных результатов. Любые предложения были бы великолепны! Спасибо
Комментарии:
1. Имеет ли страна H #A_any2 также значение 1 из — за двух .5?
2. нет, просто PA_any2, так как значения рассматриваются как факторы, а не числовые
Ответ №1:
IIUC, попробуй:
dfi = (df.loc[:, 'values']
.explode()
.groupby(level=0)
.value_counts()
.rename('count')
.reset_index())
dfi = dfi.query('values != 0.0 and count > 1')
(df.assign(**pd.crosstab(dfi['level_0'],
dfi['count']).reindex([4,3,2],
fill_value=0, axis=1)
.add_prefix('#A_all')).fillna(0))
Выход:
country region values #A_all4 #A_all3 #A_all2
0 A CA [0, 0, 1, 0.5] 0.0 0.0 0.0
1 B NE [0, 0, 0, 1] 0.0 0.0 0.0
2 C CA [1, 1, 1, 0.5] 0.0 1.0 0.0
3 D CA [1, 0, 1, 0.5] 0.0 0.0 1.0
4 E EE [0, 0.5, 0.5, 0] 0.0 0.0 1.0
5 F NE [0, 1, 1, 1] 0.0 1.0 0.0
6 G EE [0, 0, 0, 0] 0.0 0.0 0.0
7 H NE [0, 0.5, 1, 0.5] 0.0 0.0 1.0
8 I EE [nan, 0] 0.0 0.0 0.0
Комментарии:
1. это не помогает мне получить другие значения
2. @mpatil я не понимаю. Не могли бы вы уточнить?
3. это помогает мне получить колонку «А», но у меня есть другие колонки, перечисленные в квестоне. Кроме того, значение .5 считается числовым значением, но оно рассматривается как фактор/объект.
Ответ №2:
Вы можете попробовать это, однако это не совсем то же самое, что вам нужно было бы заранее заменить значения nan и удалить столбцы без полива:
from collections import Counter
def func(ls):
v,c = Counter(ls).most_common()[0]
return 0 if v is '0' else c
df['v'] = df['values'].map(func)
df['v1'] = 1
df_all = df.pivot(columns=['v'], values=['v1']).fillna(0)
df_all.columns = ["all_" str(x) for _,x in df_all.columns]
df.join(df_all).drop(['v', 'v1'], axis=1)
# country region values all_0 all_1 all_2 all_3
# 0 A CA [0, 0, 1, .5] 1.0 0.0 0.0 0.0
# 1 B NE [0, 0, 0, 1] 1.0 0.0 0.0 0.0
# 2 C CA [1, 1, 1, .5] 0.0 0.0 0.0 1.0
# 3 D CA [1, 0, 1, .5] 0.0 0.0 1.0 0.0
# 4 E EE [0, .5, .5, 0] 1.0 0.0 0.0 0.0
# 5 F NE [0, 1, 1, 1] 0.0 0.0 0.0 1.0
# 6 G EE [0, 0, 0, 0] 1.0 0.0 0.0 0.0
# 7 H NE [0, .5, 1, .5] 0.0 0.0 1.0 0.0
# 8 I EE [nan, 0] 0.0 1.0 0.0 0.0