#python #pandas #dataframe #for-loop
#python #pandas #фрейм данных #for-цикл
Вопрос:
В настоящее время я впервые пытаюсь выполнить итерацию по набору столбцов (внутри df) с целью создания двух новых столбцов с:
1). тот, который суммирует количество единиц в столбцах, которые он повторил через 2). второй столбец, если в каком-либо из итерированных столбцов есть 1, он помещает единицу в новый столбец и разрывается. *** Я решил эту часть ***
ДОБАВЛЕН МОЙ DF для контекста:
INDEX ID STATE Filed_Month ... MI HD Stroke Diabeties_all
0 0 20190 Alabama January ... 2.0 2.0 2.0 3.0
1 1 20191 Alabama January ... 2.0 2.0 2.0 3.0
2 2 20192 Alabama January ... 2.0 2.0 2.0 1.0
3 3 20193 Alabama January ... 2.0 2.0 2.0 3.0
4 4 20194 Alabama January ... 2.0 2.0 2.0 3.0
[5 rows x 13 columns]
Я также должен упомянуть, что при суммировании 1 меня интересуют только 7 из 13 столбцов.
Я смог получить вторую часть своего вопроса, используя следующее:
def ifanyCM(row):
if row["Asthma"] == 1:
return 1
if row["Asthma"] != 1:
return 0
if row["COPD_all"] == 1:
return 1
if row["COPD_all"] != 1:
return 0
if row["Skin_Cancer"] == 1:
return 1
if row["Skin_Cancer"] != 1:
return 0
if row["Other_Cancer"] == 1:
return 1
if row["Other_Cancer"] != 1:
return 0
if row["MI"] == 1:
return 1
if row["MI"] != 1:
return 0
if row["HD"] == 1:
return 1
if row["HD"] != 1:
return 0
if row["Stroke"] == 1:
return 1
if row["Stroke"] != 1:
return 0
if row["Diabeties_all"] == 1:
return 1
if row["Diabeties_all"] != 1:
return 0
y2019_r1["CM"] = y2019_r1.apply(lambda row: ifanyCM(row), axis=1)
Я просто пытаюсь подсчитать те, которые представляют интерес для 7 столбцов.
Приветствия,
Рейчел
Комментарии:
1. можете ли вы опубликовать содержимое (в виде текста)
print(df)
?
Ответ №1:
Неясно, как выглядит ваш фрейм данных. Но предполагая, что это широкий фрейм данных, подобный этому:
import pandas
import numpy
df = pandas.DataFrame({
1: [1, 2, 1, 2, 7, 1, 1, 9],
2: [2, 9, 2, 2, 2, 1, numpy.nan, numpy.nan]
}).fillna(0).astype(int).T.rename(
index=lambda r: f"row{r}",
columns=lambda r: f"col{r}",
)
col0 col1 col2 col3 col4 col5 col6 col7
row1 1 2 1 2 7 1 1 9
row2 2 9 2 2 2 1 0 0
Тогда вам не нужны никакие циклы или .apply
вообще (потому apply
что это то же самое, что и цикл:
data = df.assign(
CountOfOnes=lambda df: df.eq(1).sum(axis=1),
HasAnyOne=lambda df: df.eq(1).any(axis=1)
)
Который есть:
col0 col1 col2 col3 col4 col5 col6 col7 CountOfOnes HasAnyOne
row1 1 2 1 2 7 1 1 9 4 True
row2 2 9 2 2 2 1 0 0 1 True
Ответ №2:
Простой способ сделать это — использовать df.apply() с лямбда-функцией в pandas. Когда вы укажете axis=1, он обработает строку a в фрейме данных как серию. В приведенном ниже примере я подсчитал длину понимания списка, в котором сохранялись только значения 1 в строке, чтобы подсчитать количество единиц. Впоследствии я использовал другой df.apply() для столбца с общим числом 1, чтобы проверить, содержит ли он значение больше 0.
import pandas as pd
l = [[1, 2, 1, 2, 7, 1],[2, 9, 2, 2, 2, 2]]
df= pd.DataFrame(l)
df['total 1s'] = df[[0,1,2,3,4,5]].apply(lambda row: len([i for i in row if i == 1]), axis=1)
df['any 1s'] = df['total 1s'].apply(lambda x: False if x == 0 else True)
Результат:
---- ----- ----- ----- ----- ----- ----- ------------ ----------
| | 0 | 1 | 2 | 3 | 4 | 5 | total 1s | any 1s |
|---- ----- ----- ----- ----- ----- ----- ------------ ----------|
| 0 | 1 | 2 | 1 | 2 | 7 | 1 | 3 | True |
| 1 | 2 | 9 | 2 | 2 | 2 | 2 | 0 | False |
---- ----- ----- ----- ----- ----- ----- ------------ ----------
Комментарии:
1. Большое вам спасибо! Я понятия не имел о df.apply fx!!