#python #pandas #dataframe
Вопрос:
Учитывая df1, я знаю, как получить значения в ячейках с помощью .value_counts()
:
df1 = pd.DataFrame({'numbers': [0.1, 0.11, 0.2, 0.3, 0.33, 0.6, 0.66, 0.7, 0.9, 1],
'another_column': ['blue', 'blue', 'blue', 'red', 'green', 'purple', 'blue', 'blue', 'blue', 'orange']})
df1['numbers'].value_counts(bins=[0, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1])
Результат:
(0.6, 0.7] 2
(0.1, 0.2] 2
(0.9, 1.0] 1
(0.8, 0.9] 1
(0.5, 0.6] 1
(0.3, 0.4] 1
(0.2, 0.3] 1
(-0.001, 0.1] 1
(0.7, 0.8] 0
(0.4, 0.5] 0
Name: numbers, dtype: int64
Учитывая, что другой df намного больше, чем df1 (пример ниже):
df2 = pd.DataFrame({'numbers': [0.1, 0.11, 0.2, 0.3, 0.33, 0.6, 0.66, 0.7, 0.9, 0.1, 0.11, 0.2, 0.3, 0.33, 0.6, 0.66, 0.7, 0.9, 0.1, 0.11, 0.2, 0.3, 0.33, 0.6, 0.66, 0.7, 0.98],
'nonshared_column': ['cat', 'dog', 'cat', 'dog', 'fish', 'cat', 'dog', 'dog', 'fish', 'cat', 'dog', 'cat', 'dog', 'fish', 'cat', 'dog', 'dog', 'fish', 'cat', 'dog', 'cat', 'dog', 'fish', 'cat', 'dog', 'dog', 'fish']})
Я хочу взять ячейки из df1 для фильтрации df2, поэтому выходной df является подмножеством df2, которое соответствует ячейкам из df1,
таким образом, выходной df будет иметь 1 строку со значениями «чисел» между 0-0, 1, 2 строками со значениями «чисел» между 0,1-0,2 … вплоть до 1 строки со значениями «чисел» в диапазоне от 0,9 до 1. Выходные строки df должны включать все столбцы из df2 ( nonshared_column
в этом примере, а также numbers
столбец).
Ответ №1:
Использовать cut
bins
с индексом от по Series
имени s
:
s = df1['numbers'].value_counts(bins=[0, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1])
df2['new'] = pd.cut(df2['numbers'], bins=s.index)
print (df2)
numbers nonshared_column new
0 0.10 cat (-0.001, 0.1]
1 0.11 dog (0.1, 0.2]
2 0.20 cat (0.1, 0.2]
3 0.30 dog (0.2, 0.3]
4 0.33 fish (0.3, 0.4]
5 0.60 cat (0.5, 0.6]
6 0.66 dog (0.6, 0.7]
7 0.70 dog (0.6, 0.7]
8 0.90 fish (0.8, 0.9]
9 0.10 cat (-0.001, 0.1]
10 0.11 dog (0.1, 0.2]
11 0.20 cat (0.1, 0.2]
12 0.30 dog (0.2, 0.3]
13 0.33 fish (0.3, 0.4]
14 0.60 cat (0.5, 0.6]
15 0.66 dog (0.6, 0.7]
16 0.70 dog (0.6, 0.7]
17 0.90 fish (0.8, 0.9]
18 0.10 cat (-0.001, 0.1]
19 0.11 dog (0.1, 0.2]
20 0.20 cat (0.1, 0.2]
21 0.30 dog (0.2, 0.3]
22 0.33 fish (0.3, 0.4]
23 0.60 cat (0.5, 0.6]
24 0.66 dog (0.6, 0.7]
25 0.70 dog (0.6, 0.7]
26 0.98 fish (0.9, 1.0]
Последнее, если нужно, количество по всем 3 столбцам:
df3 = df2.groupby(['numbers','nonshared_column','new'], observed=True).size().reset_index(name='count')
print (df3)
numbers nonshared_column new count
0 0.10 cat (-0.001, 0.1] 3
1 0.11 dog (0.1, 0.2] 3
2 0.20 cat (0.1, 0.2] 3
3 0.30 dog (0.2, 0.3] 3
4 0.33 fish (0.3, 0.4] 3
5 0.60 cat (0.5, 0.6] 3
6 0.66 dog (0.6, 0.7] 3
7 0.70 dog (0.6, 0.7] 3
8 0.90 fish (0.8, 0.9] 2
9 0.98 fish (0.9, 1.0] 1
Редактировать:
Если нужно то же самое, например s
, сначала используйте sample
для случайного порядка строк, а затем head()
с помощью map by s
для фильтрации по количеству:
df2 = df2.sample(frac=1).groupby('new', group_keys=False).apply(lambda x: x.head(s[x.name])).sort_index()
print (df2)
numbers nonshared_column new
2 0.20 cat (0.1, 0.2]
3 0.30 dog (0.2, 0.3]
4 0.33 fish (0.3, 0.4]
9 0.10 cat (-0.001, 0.1]
11 0.20 cat (0.1, 0.2]
14 0.60 cat (0.5, 0.6]
15 0.66 dog (0.6, 0.7]
17 0.90 fish (0.8, 0.9]
24 0.66 dog (0.6, 0.7]
26 0.98 fish (0.9, 1.0]
Комментарии:
1. Это отлично подходит для первой части! Как насчет случайного выбора строк из df2, чтобы у него было то же количество ячеек, что и у df1?