나는이 6 개 열 (에 (그것이 경우 – 다른 사다리를 사용) 내 사용자 지정 기능을 적용 할 ERI_Hispanic
, ERI_AmerInd_AKNatv
, ERI_Asian
, ERI_Black_Afr.Amer
, ERI_HI_PacIsl
, ERI_White
내 dataframe의 각 행).
다른 질문과 다른 방법을 시도했지만 여전히 내 문제에 대한 올바른 답변을 찾지 못하는 것 같습니다. 이것의 중요한 부분은 사람이 히스패닉으로 간주되면 다른 것으로 계산할 수 없다는 것입니다. 다른 민족 열에 “1”이 있어도 둘 이상의 인종이 아닌 히스패닉으로 간주됩니다. 마찬가지로 모든 ERI 열의 합계가 1보다 크면 두 개 이상의 인종으로 계산되며 고유 한 민족으로 계산할 수 없습니다 (히스패닉 제외). 잘만되면 이것이 의미가 있습니다. 어떤 도움이라도 대단히 감사하겠습니다.
각 행을 통해 for 루프를 수행하는 것과 거의 같으며 각 레코드가 기준을 충족하면 하나의 목록에 추가되고 원본에서 제거됩니다.
아래 데이터 프레임에서 SQL의 다음 사양을 기반으로 새 열을 계산해야합니다.
========================= CRITERIA ========================= =======
IF [ERI_Hispanic] = 1 THEN RETURN “Hispanic”
ELSE IF SUM([ERI_AmerInd_AKNatv] + [ERI_Asian] + [ERI_Black_Afr.Amer] + [ERI_HI_PacIsl] + [ERI_White]) > 1 THEN RETURN “Two or More”
ELSE IF [ERI_AmerInd_AKNatv] = 1 THEN RETURN “A/I AK Native”
ELSE IF [ERI_Asian] = 1 THEN RETURN “Asian”
ELSE IF [ERI_Black_Afr.Amer] = 1 THEN RETURN “Black/AA”
ELSE IF [ERI_HI_PacIsl] = 1 THEN RETURN “Haw/Pac Isl.”
ELSE IF [ERI_White] = 1 THEN RETURN “White”
의견 : 히스패닉계 ERI 플래그가 True (1) 인 경우 직원은 “히스패닉”으로 분류됩니다.
코멘트 : 비 히스패닉 ERI 플래그가 둘 이상인 경우 “2 이상”을 반환하십시오.
====================== DATAFRAME ============================
lname fname rno_cd eri_afr_amer eri_asian eri_hawaiian eri_hispanic eri_nat_amer eri_white rno_defined
0 MOST JEFF E 0 0 0 0 0 1 White
1 CRUISE TOM E 0 0 0 1 0 0 White
2 DEPP JOHNNY 0 0 0 0 0 1 Unknown
3 DICAP LEO 0 0 0 0 0 1 Unknown
4 BRANDO MARLON E 0 0 0 0 0 0 White
5 HANKS TOM 0 0 0 0 0 1 Unknown
6 DENIRO ROBERT E 0 1 0 0 0 1 White
7 PACINO AL E 0 0 0 0 0 1 White
8 WILLIAMS ROBIN E 0 0 1 0 0 0 White
9 EASTWOOD CLINT E 0 0 0 0 0 1 White
답변
좋아, 이것에 대한 두 단계-먼저 원하는 번역을 수행하는 함수를 작성하는 것입니다-의사 코드를 기반으로 예제를 작성했습니다.
def label_race (row):
if row['eri_hispanic'] == 1 :
return 'Hispanic'
if row['eri_afr_amer'] + row['eri_asian'] + row['eri_hawaiian'] + row['eri_nat_amer'] + row['eri_white'] > 1 :
return 'Two Or More'
if row['eri_nat_amer'] == 1 :
return 'A/I AK Native'
if row['eri_asian'] == 1:
return 'Asian'
if row['eri_afr_amer'] == 1:
return 'Black/AA'
if row['eri_hawaiian'] == 1:
return 'Haw/Pac Isl.'
if row['eri_white'] == 1:
return 'White'
return 'Other'
이것을 넘어 가고 싶을 수도 있지만, 트릭을 수행하는 것 같습니다. 함수로 들어가는 매개 변수는 “row”라는 레이블이 붙은 Series 객체로 간주됩니다.
다음으로 팬더의 적용 기능을 사용하여 기능을 적용하십시오.
df.apply (lambda row: label_race(row), axis=1)
axis = 1 지정자는 응용 프로그램이 열 수준이 아니라 행에서 수행됨을 의미합니다. 결과는 다음과 같습니다.
0 White
1 Hispanic
2 White
3 White
4 Other
5 White
6 Two Or More
7 White
8 Haw/Pac Isl.
9 White
결과가 마음에 들면 결과를 다시 실행하여 원래 데이터 프레임의 새 열에 결과를 저장하십시오.
df['race_label'] = df.apply (lambda row: label_race(row), axis=1)
결과 데이터 프레임은 다음과 같습니다 (오른쪽으로 스크롤하여 새 열을 봅니다).
lname fname rno_cd eri_afr_amer eri_asian eri_hawaiian eri_hispanic eri_nat_amer eri_white rno_defined race_label
0 MOST JEFF E 0 0 0 0 0 1 White White
1 CRUISE TOM E 0 0 0 1 0 0 White Hispanic
2 DEPP JOHNNY NaN 0 0 0 0 0 1 Unknown White
3 DICAP LEO NaN 0 0 0 0 0 1 Unknown White
4 BRANDO MARLON E 0 0 0 0 0 0 White Other
5 HANKS TOM NaN 0 0 0 0 0 1 Unknown White
6 DENIRO ROBERT E 0 1 0 0 0 1 White Two Or More
7 PACINO AL E 0 0 0 0 0 1 White White
8 WILLIAMS ROBIN E 0 0 1 0 0 0 White Haw/Pac Isl.
9 EASTWOOD CLINT E 0 0 0 0 0 1 White White
답변
이것이 ‘다른 사람들의 팬더 새 열’에 대한 첫 번째 Google 결과이므로 다음은 간단한 예입니다.
import pandas as pd
# make a simple dataframe
df = pd.DataFrame({'a':[1,2], 'b':[3,4]})
df
# a b
# 0 1 3
# 1 2 4
# create an unattached column with an index
df.apply(lambda row: row.a + row.b, axis=1)
# 0 4
# 1 6
# do same but attach it to the dataframe
df['c'] = df.apply(lambda row: row.a + row.b, axis=1)
df
# a b c
# 0 1 3 4
# 1 2 4 6
당신 SettingWithCopyWarning
이 그것을 얻는다면 당신은 또한 이렇게 할 수 있습니다 :
fn = lambda row: row.a + row.b # define a function for the new column
col = df.apply(fn, axis=1) # get column data with an index
df = df.assign(c=col.values) # assign values to column 'c'
출처 : https://stackoverflow.com/a/12555510/243392
그리고 열 이름에 공백이 있으면 다음과 같은 구문을 사용할 수 있습니다.
df = df.assign(**{'some column name': col.values})
여기에 apply 및 assign에 대한 설명서가 있습니다 .
답변
위의 답변은 완벽하게 유효하지만 벡터화 된 솔루션은의 형태로 존재합니다 numpy.select
. 이를 통해 조건을 정의한 다음 해당 조건에 대한 출력을 정의 할 수 있습니다 apply
.
먼저 조건을 정의하십시오.
conditions = [
df['eri_hispanic'] == 1,
df[['eri_afr_amer', 'eri_asian', 'eri_hawaiian', 'eri_nat_amer', 'eri_white']].sum(1).gt(1),
df['eri_nat_amer'] == 1,
df['eri_asian'] == 1,
df['eri_afr_amer'] == 1,
df['eri_hawaiian'] == 1,
df['eri_white'] == 1,
]
이제 해당 출력을 정의하십시오.
outputs = [
'Hispanic', 'Two Or More', 'A/I AK Native', 'Asian', 'Black/AA', 'Haw/Pac Isl.', 'White'
]
마지막으로 다음을 사용하십시오 numpy.select
.
res = np.select(conditions, outputs, 'Other')
pd.Series(res)
0 White
1 Hispanic
2 White
3 White
4 Other
5 White
6 Two Or More
7 White
8 Haw/Pac Isl.
9 White
dtype: object
왜해야 numpy.select
이상 사용할 수 apply
? 성능 검사는 다음과 같습니다.
df = pd.concat([df]*1000)
In [42]: %timeit df.apply(lambda row: label_race(row), axis=1)
1.07 s ± 4.16 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [44]: %%timeit
...: conditions = [
...: df['eri_hispanic'] == 1,
...: df[['eri_afr_amer', 'eri_asian', 'eri_hawaiian', 'eri_nat_amer', 'eri_white']].sum(1).gt(1),
...: df['eri_nat_amer'] == 1,
...: df['eri_asian'] == 1,
...: df['eri_afr_amer'] == 1,
...: df['eri_hawaiian'] == 1,
...: df['eri_white'] == 1,
...: ]
...:
...: outputs = [
...: 'Hispanic', 'Two Or More', 'A/I AK Native', 'Asian', 'Black/AA', 'Haw/Pac Isl.', 'White'
...: ]
...:
...: np.select(conditions, outputs, 'Other')
...:
...:
3.09 ms ± 17 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
를 사용 numpy.select
하면 성능이 크게 향상되며 데이터가 증가함에 따라 불일치 만 증가합니다.
답변
.apply()
함수를 첫 번째 매개 변수로 취합니다. 다음과 같이 label_race
함수를 전달하십시오 .
df['race_label'] = df.apply(label_race, axis=1)
함수를 전달하기 위해 람다 함수를 만들 필요는 없습니다.
답변
이 시도,
df.loc[df['eri_white']==1,'race_label'] = 'White'
df.loc[df['eri_hawaiian']==1,'race_label'] = 'Haw/Pac Isl.'
df.loc[df['eri_afr_amer']==1,'race_label'] = 'Black/AA'
df.loc[df['eri_asian']==1,'race_label'] = 'Asian'
df.loc[df['eri_nat_amer']==1,'race_label'] = 'A/I AK Native'
df.loc[(df['eri_afr_amer'] + df['eri_asian'] + df['eri_hawaiian'] + df['eri_nat_amer'] + df['eri_white']) > 1,'race_label'] = 'Two Or More'
df.loc[df['eri_hispanic']==1,'race_label'] = 'Hispanic'
df['race_label'].fillna('Other', inplace=True)
O / P :
lname fname rno_cd eri_afr_amer eri_asian eri_hawaiian \
0 MOST JEFF E 0 0 0
1 CRUISE TOM E 0 0 0
2 DEPP JOHNNY NaN 0 0 0
3 DICAP LEO NaN 0 0 0
4 BRANDO MARLON E 0 0 0
5 HANKS TOM NaN 0 0 0
6 DENIRO ROBERT E 0 1 0
7 PACINO AL E 0 0 0
8 WILLIAMS ROBIN E 0 0 1
9 EASTWOOD CLINT E 0 0 0
eri_hispanic eri_nat_amer eri_white rno_defined race_label
0 0 0 1 White White
1 1 0 0 White Hispanic
2 0 0 1 Unknown White
3 0 0 1 Unknown White
4 0 0 0 White Other
5 0 0 1 Unknown White
6 0 0 1 White Two Or More
7 0 0 1 White White
8 0 0 0 White Haw/Pac Isl.
9 0 0 1 White White
.loc
대신에 사용하십시오 apply
.
벡터화를 향상시킵니다.
.loc
간단한 방식으로 작동하고 조건에 따라 행을 마스크하고 고정 행에 값을 적용합니다.
자세한 내용은 .loc docs를 방문하십시오.
성능 측정 항목 :
허용 된 답변 :
def label_race (row):
if row['eri_hispanic'] == 1 :
return 'Hispanic'
if row['eri_afr_amer'] + row['eri_asian'] + row['eri_hawaiian'] + row['eri_nat_amer'] + row['eri_white'] > 1 :
return 'Two Or More'
if row['eri_nat_amer'] == 1 :
return 'A/I AK Native'
if row['eri_asian'] == 1:
return 'Asian'
if row['eri_afr_amer'] == 1:
return 'Black/AA'
if row['eri_hawaiian'] == 1:
return 'Haw/Pac Isl.'
if row['eri_white'] == 1:
return 'White'
return 'Other'
df=pd.read_csv('dataser.csv')
df = pd.concat([df]*1000)
%timeit df.apply(lambda row: label_race(row), axis=1)
루프 당 1.15 초 ± 46.5ms (평균 7 회 실행, 각 1 회 루프)
내 제안 된 답변 :
def label_race(df):
df.loc[df['eri_white']==1,'race_label'] = 'White'
df.loc[df['eri_hawaiian']==1,'race_label'] = 'Haw/Pac Isl.'
df.loc[df['eri_afr_amer']==1,'race_label'] = 'Black/AA'
df.loc[df['eri_asian']==1,'race_label'] = 'Asian'
df.loc[df['eri_nat_amer']==1,'race_label'] = 'A/I AK Native'
df.loc[(df['eri_afr_amer'] + df['eri_asian'] + df['eri_hawaiian'] + df['eri_nat_amer'] + df['eri_white']) > 1,'race_label'] = 'Two Or More'
df.loc[df['eri_hispanic']==1,'race_label'] = 'Hispanic'
df['race_label'].fillna('Other', inplace=True)
df=pd.read_csv('s22.csv')
df = pd.concat([df]*1000)
%timeit label_race(df)
루프 당 24.7ms ± 1.7ms (평균 7 번의 런, 평균 10 개의 루프)