Скажем, у меня есть кадр данных, df
:
>>> df
Age Score
19 1
20 2
24 3
19 2
24 3
24 1
24 3
20 1
19 1
20 3
22 2
22 1
Я хочу создать новый фрейм данных, который содержит Age
и сохраняет общее количество элементов в каждом из бинов в разных столбцах Score
:
Age Score 1 Score 2 Score 3
19-21 2 4 3
22-24 2 2 9
Это мой способ сделать это, который я считаю очень запутанным (это означает, что это не должно быть так сложно):
import numpy as np
import pandas as pd
data = pd.DataFrame(columns=['Age', 'Score'])
data['Age'] = [19,20,24,19,24,24,24,20,19,20,22,22]
data['Score'] = [1,2,3,2,3,1,3,1,1,3,2,1]
_, bins = np.histogram(data['Age'], 2)
labels = ['{}-{}'.format(i + 1, j) for i, j in zip(bins[:-1], bins[1:])] #dynamically create labels
labels[0] = '{}-{}'.format(bins[0], bins[1])
df = pd.DataFrame(columns=['Score', labels[0], labels[1]])
df['Score'] = data.Score.unique()
for i in labels:
df[i] = np.zeros(3)
for i in range(len(data)):
for j in range(len(labels)):
m1, m2 = labels[j].split('-') # lower & upper bounds of the age interval
if ((float(data['Age'][i])>float(m1)) & (float(data['Age'][i])<float(m2))): # find the age group in which each age lies
if data['Score'][i]==1:
index = 0
elif data['Score'][i]==2:
index = 1
elif data['Score'][i]==3:
index = 2
df[labels[j]][index] += 1
df.sort_values('Score', inplace=True)
df.set_index('Score', inplace=True)
print(df)
Это производит
19.0-21.5 22.5-24.0
Score
1 2.0 2.0
2 4.0 2.0
3 3.0 9.0
Есть ли лучший, более чистый, более эффективный способ достижения этого?
pd.crosstab(pd.cut(df.Age, [19, 21, 24]), df.Score)
... - person Jon Clements♦   schedule 08.08.2018