Как вы выполняете операторы If и Else If в рамках DataFrame? - PullRequest
3 голосов
/ 29 сентября 2019

У меня есть Dataframe, df, и я удивляюсь, как вы выполняете операторы If и Else If, ​​и если ни один из этих операторов 'if / elseif' не встречается, строки должны оставаться неизменными. Таким образом, если df ['Age'] равно 9, (Оценка 1 = 5, Оценка 2 = 7) В противном случае, если df ['Age'] равно 10, (Оценка 1 = 10, Оценка 2 = 12) В противном случае оставьте строки без изменений. ,Было бы идеально использовать лямбда-функции.

До;

Age    Score 1    Score 2    AA

9      13.0         3.5      144
10     12.0         3.1      133
9      11.0         2.8      100
8      14.0         1.5      110
14     14.0         1.2      97

После;

Age    Score 1    Score 2    AA

9      5.0          7.0      144
10     10.0         12.0      133
9      5.0          7.0      100
8      14.0         1.5      110
14     14.0         1.2      97

1 Ответ

1 голос
/ 29 сентября 2019

Одна идея - использовать DataFrame.loc с условием и указать оба столбца в списке - так можно назначить список [5,7]:

df.loc[df['Age'] == 9, ['Score 1','Score 2']] = [5,7]
df.loc[df['Age'] == 10, ['Score 1','Score 2']] = [10,12]
print (df)
   Age  Score 1  Score 2   AA
0    9      5.0      7.0  144
1   10     10.0     12.0  133
2    9      5.0      7.0  100
3    8     14.0      1.5  110
4   14     14.0      1.2   97

Другая - использовать numpy.select с широковещательной передачей, поскольку работа с обоими столбцами:

m1 = df['Age'].eq(9).values[:, None]
m2 = df['Age'].eq(10).values[:, None]

v1 = [5,7]
v2 = [10, 12]

df[['Score 1','Score 2']] = np.select([m1, m2], [v1, v2], default = df[['Score 1','Score 2']])

print (df)
   Age  Score 1  Score 2   AA
0    9      5.0      7.0  144
1   10     10.0     12.0  133
2    9      5.0      7.0  100
3    8     14.0      1.5  110
4   14     14.0      1.2   97

Решение с использованием лямбды возможно, но очень медленно:

s = pd.Series([5, 7], index=['Score 1','Score 2'])
f = lambda x: s if  x['Age'] == 9 else x[['Score 1', 'Score 2']]
df[['Score 1','Score 2']] = df.apply(f, axis=1)
print (df)
   Age  Score 1  Score 2   AA
0    9      5.0      7.0  144
1   10     12.0      3.1  133
2    9      5.0      7.0  100
3    8     14.0      1.5  110
4   14     14.0      1.2   97

Производительность :

#5k rows
df = pd.concat([df] * 1000, ignore_index=True)

In [113]: %timeit df.loc[df['Age'] == 9, ['Score 1','Score 2']] = [5,7]
2.35 ms ± 28.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [114]: %timeit df[['Score 1','Score 2']] = df.apply(lambda x: pd.Series([5, 7], index=['Score 1','Score 2']) if  x['Age'] == 9 else x[['Score 1', 'Score 2']], axis=1)
2.88 s ± 138 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Производительность первых 2 решений для большего количества строк:

#50k rows
df = pd.concat([df] * 10000, ignore_index=True)

In [120]: %%timeit
     ...: df.loc[df['Age'] == 9, ['Score 1','Score 2']] = [5,7]
     ...: df.loc[df['Age'] == 10, ['Score 1','Score 2']] = [10,12]
     ...: 
6.33 ms ± 59.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [121]: %%timeit
     ...: df[['Score 1','Score 2']] = np.select([df['Age'].eq(9).values[:, None], df['Age'].eq(10).values[:, None]], [[5,7], [10, 12]], df[['Score 1','Score 2']])
     ...: 
19.1 ms ± 139 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...