#python #pandas
#python #pandas
Вопрос:
Мой фрейм данных выглядит следующим образом:
id column1 column2
a x l
a x n
a y n
b y l
b y m
В настоящее время я генерирую подсчеты значений с помощью этого
def value_occurences(grouped, column_name):
return (grouped[column_name].value_counts(normalize=False, dropna=False)
.to_frame('count_' column_name)
.reset_index(level=1))
result = value_occurences(grouped, 'column1')
"""
>>>result
id column1 count_column1
a x 2
a y 1
b y 1
"""
И мне нужно подсчитать вхождения значений в этом формате:
id column1 column2
a 'x:2; y:1' 'l:1; n:2'
b 'y:1' 'l:1; m:1'
как я могу преобразовать свой результат в этот формат?
Ответ №1:
Я знаю, что здесь не используются Pandas, но это все равно может вам помочь:
from collections import defaultdict
import pandas as pd
df = pd.DataFrame({'id': ['a', 'a', 'a', 'b', 'b'], 'column1': ['x', 'x', 'y', 'y', 'y'], 'column2': ['l', 'n', 'n', 'l', 'm']})
# id column1 column2
# 0 a x l
# 1 a x n
# 2 a y n
# 3 b y l
# 4 b y m
c1_counter = defaultdict(lambda: defaultdict(int))
c2_counter = defaultdict(lambda: defaultdict(int))
for idx, row in df.iterrows():
c1_counter[row['id']][row['column1']] = 1
c2_counter[row['id']][row['column2']] = 1
new_data = defaultdict(list)
for k, v in c1_counter.items():
new_data['id'].append(k)
c1_items = [f'{v_}:{f}' for v_, f in v.items()]
c2_items = [f'{v_}:{f}' for v_, f in c2_counter[k].items()]
new_data['column1'].append(';'.join(c1_items))
new_data['column2'].append(';'.join(c2_items))
df = pd.DataFrame(new_data)
тогда df
будет выглядеть:
id column1 column2
0 a x:2;y:1 l:1;n:2
1 b y:2 l:1;m:1
Ответ №2:
Вы можете сначала сгенерировать группы df
по df.groupby(['id'])
и применить value_counts
к каждой группе:
import io, pandas as pd
def seqdict(x):
return ', '.join('{}:{}'.format(*i) for i in sorted(x.items()))
def value_occurences(df):
return pd.DataFrame({c: {i: seqdict(d.iloc[:,j].value_counts().to_dict())
for i, d in df.groupby(by=['id']) }
for j, c in enumerate(df.keys())
})
grouped = pd.read_table(io.StringIO("""id column1 column2
a x l
a x n
a y n
b y l
b y m
"""), sep='s ')
value_occurences(grouped)
Результаты:
column1 column2
a x:2, y:1 l:1, n:2
b y:2 l:1, m:1
Ответ №3:
Вы можете использовать groupby
дважды. Добавьте, сначала вы подсчитываете значения, а затем объединяете их вместе:
dfs = []
for column in ['column1', 'column2']:
df_ = df.groupby(['id'])[column].value_counts()
df_ = df_.index.get_level_values(-1) ':' df_.astype(str)
df_ = df_.groupby('id').agg(lambda x: '; '.join(x)).rename(column)
dfs.append(df_)
pd.concat(dfs, axis=1)