сравнение строк в фрейме данных - PullRequest
2 голосов
/ 08 апреля 2019

У меня проблемы с одной из моих задач.в моем первом случае мне нужно сравнить некоторые переменные в моем фрейме данных, затем, если они будут одинаковыми, он вернет одинаковое значение столбца идентификатора.

вот мой несколько отсортированных просмотров фрейма данныхкак

| no | age| gender | income_group | cars
| 1  | 15 |  male  |       0      | ford
| 2  | 15 |  male  |       0      | renault
| 3  | 15 |  female|       1      | bmw
| 4  | 16 |  female|       1      | bmw
| 5  | 16 |  female|       1      | mercedes
| 6  | 16 |  female|       1      | honda

Мне нужен код, который будет сравнивать каждую строку в этом отсортированном кадре данных, и если [возраст, пол, доход_группа] одинаково для некоторых строк, будет скопировано первое значение столбца [нет] взамените другие

код заставит мой фрейм данных выглядеть следующим образом

| no | age| gender | income_group | cars
| 1  | 15 |  male  |       0      | ford
| 1  | 15 |  male  |       0      | renault
| 3  | 15 |  female|       1      | bmw
| 4  | 16 |  female|       1      | bmw
| 4  | 16 |  female|       1      | mercedes
| 4  | 16 |  female|       1      | honda

есть ли какой-нибудь способ сделать это в Python?

Отредактировано: мой второй случай усложняется, когда я нахожу какие-то идентичные переменные [age, gen ,come_group], но у меня есть одно и то же значение [cars], я хочу, чтобы его считали другим человеком, в этом случае другим[нет] значения

если развернуть фрейм данных и получить столбец выглядит следующим образом

| no | age| gender | income_group | cars
| 1  | 15 |  male  |       0      | ford
| 2  | 15 |  male  |       0      | renault
| 3  | 15 |  female|       1      | bmw
| 4  | 16 |  female|       1      | bmw
| 5  | 16 |  female|       1      | mercedes
| 6  | 16 |  female|       1      | honda

| 7  | 17 |  male  |       0      | bmw
| 8  | 17 |  male  |       0      | honda
| 9  | 17 |  male  |       0      | bmw
| 10 | 17 |  male  |       0      | honda
| 11 | 17 |  male  |       0      | renault

один человек не может иметь одно и то же значение автомобилей, код будет иметь значение df:

| 7  | 17 |  male  |       0      | bmw
| 7  | 17 |  male  |       0      | honda
| 9  | 17 |  male  |       0      | bmw
| 9  | 17 |  male  |       0      | honda
| 9  | 17 |  male  |       0      | renault

с решением Jezrael:

df['a'] = df.duplicated(['age','gender','income_group', 'cars'], keep=False).cumsum()

df['no'] = df.groupby(['age','gender','income_group','a'], sort=False)['no'].transform('first')
df = df.drop('a', axis=1)

я получаю:

no  age  gender  income_group      cars  a
 0   15    male             0      ford  0
 0   15    male             0   renault  0
 2   15  female             1       bmw  0
 3   16  female             1       bmw  0
 3   16  female             1  mercedes  0
 3   16  female             1     honda  0
 6   17    male             0       bmw  1
 7   17    male             0     honda  2
 8   17    male             0       bmw  3
 9   17    male             0     honda  4
 9   17    male             0   reanult  4

1 Ответ

6 голосов
/ 08 апреля 2019

Использование GroupBy.transform с GroupBy.first:

df['no'] = df.groupby(['age','gender','income_group'], sort=False)['no'].transform('first')
print (df)
   no  age  gender  income_group      cars
0   1   15    male             0      ford
1   1   15    male             0   renault
2   3   15  female             1       bmw
3   4   16  female             1       bmw
4   4   16  female             1  mercedes
5   4   16  female             1     honda

Или получить первые значения по DataFrame.duplicated, а затем заполнить пропущенные значения вперед:

df['no'] = df.loc[(~df.duplicated(['age','gender','income_group'])), 'no']
df['no'] = df['no'].ffill().astype(int)
print (df)
   no  age  gender  income_group      cars
0   1   15    male             0      ford
1   1   15    male             0   renault
2   3   15  female             1       bmw
3   4   16  female             1       bmw
4   4   16  female             1  mercedes
5   4   16  female             1     honda

EDIT:

df['a'] = df.duplicated(['age','gender','income_group', 'cars'])
mask = df.groupby(['age','gender','income_group'])['a'].transform('any')

df.loc[mask, 'no'] = df.groupby(df.loc[mask].groupby('cars').cumcount(ascending=False))['no'].transform('first')
df = df.drop('a', axis=1)              
print (df)
     no  age  gender  income_group      cars
0   1.0   15    male             0      ford
1   2.0   15    male             0   renault
2   3.0   15  female             1       bmw
3   4.0   16  female             1       bmw
4   5.0   16  female             1  mercedes
5   6.0   16  female             1     honda
6   7.0   17    male             0       bmw
7   7.0   17    male             0     honda
8   9.0   17    male             0       bmw
9   9.0   17    male             0     honda
10  9.0   17    male             0   reanult
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...