다른 열의 값을 기준으로 한 Pandas 열의 값 설정
Pandas 데이터 프레임의 다른 열 값을 기준으로 한 열 값을 설정해야 합니다.논리는 다음과 같습니다.
if df['c1'] == 'Value':
df['c2'] = 10
else:
df['c2'] = df['c3']
단순히 새 값으로 열을 만드는 것(또는 기존 열의 값을 변경하는 것), 즉 원하는 작업을 수행할 수 없습니다.
위의 코드를 실행하려고 하거나 함수로 작성하여 적용 방법을 사용하면 다음과 같은 메시지가 나타납니다.
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
이를 위한 한 가지 방법은 인덱싱을 사용하는 것입니다..loc
.
예
예시적인 데이터 프레임이 없는 경우, 여기서 하나를 만들어 보겠습니다.
import numpy as np
import pandas as pd
df = pd.DataFrame({'c1': list('abcdefg')})
df.loc[5, 'c1'] = 'Value'
>>> df
c1
0 a
1 b
2 c
3 d
4 e
5 Value
6 g
새 열을 생성하려고 했다고 가정합니다. c2
와 동등한.c1
경우를 제외하고c1
이라Value
이 경우 10에 할당하려고 합니다.
먼저 새 열을 생성할 수 있습니다.c2
다음과 같은 값으로 설정합니다.c1
다음 두 줄 중 하나를 사용합니다(기본적으로 동일한 작업을 수행함).
df = df.assign(c2 = df['c1'])
# OR:
df['c2'] = df['c1']
그런 다음, 모든 인덱스를 찾습니다.c1
와 같음'Value'
사용..loc
원하는 값을 지정합니다.c2
다음 지수에서:
df.loc[df['c1'] == 'Value', 'c2'] = 10
결국 다음과 같은 결과가 됩니다.
>>> df
c1 c2
0 a a
1 b b
2 c c
3 d d
4 e e
5 Value 10
6 g g
질문에서 제안한 것처럼 새 열을 만드는 대신 이미 있는 열의 값을 바꾸기를 원할 수도 있습니다. 그런 다음 열 만들기를 건너뛰고 다음을 수행하십시오.
df['c1'].loc[df['c1'] == 'Value'] = 10
# or:
df.loc[df['c1'] == 'Value', 'c1'] = 10
제공:
>>> df
c1
0 a
1 b
2 c
3 d
4 e
5 10
6 g
를 사용하여 지정된 조건을 기준으로 값을 설정할 수 있습니다.
#df
c1 c2 c3
0 4 2 1
1 8 7 9
2 1 5 8
3 3 3 5
4 3 6 8
이제 열에서 값 변경(또는 설정)['c2']
당신의 상태에 따라.
df['c2'] = np.where(df.c1 == 8,'X', df.c3)
c1 c2 c3
0 4 1 1
1 8 X 9
2 1 8 8
3 3 5 5
4 3 8 8
시도:
df['c2'] = df['c1'].apply(lambda x: 10 if x == 'Value' else x)
선택을 반대로 하는 기울기를 기록합니다.그것은 판다 방법을 사용합니다. (즉, 보다 빠릅니다.if
/else
).
df.loc[(df['c1'] == 'Value'), 'c2'] = 10
df.loc[~(df['c1'] == 'Value'), 'c2'] = df['c3']
두 단계로 진행하는 것이 좋습니다.
# set fixed value to 'c2' where the condition is met
df.loc[df['c1'] == 'Value', 'c2'] = 10
# copy value from 'c3' to 'c2' where the condition is NOT met
df.loc[df['c1'] != 'Value', 'c2'] = df[df['c1'] != 'Value', 'c3']
사용할 수 있습니다.pandas.DataFrame.mask
필요한 만큼의 조건을 추가할 수 있습니다.
data = {'a': [1,2,3,4,5], 'b': [6,8,9,10,11]}
d = pd.DataFrame.from_dict(data, orient='columns')
c = {'c1': (2, 'Value1'), 'c2': (3, 'Value2'), 'c3': (5, d['b'])}
d['new'] = np.nan
for value in c.values():
d['new'].mask(d['a'] == value[0], value[1], inplace=True)
d['new'] = d['new'].fillna('Else')
d
출력:
a b new
0 1 6 Else
1 2 8 Value1
2 3 9 Value2
3 4 10 Else
4 5 11 11
Series.map()은 다음과 같이 매우 읽기 쉽고 효율적이라고 생각합니다.
df["c2"] = df["c1"].map(lambda x: 10 if x == 'Value' else x)
조건부 논리가 더 복잡해지면 함수로 이동하여 람다 대신 해당 함수를 전달할 수 있기 때문에 좋습니다.
조건부 논리를 둘 이상의 열에 기반해야 하는 경우 다른 사람이 제안하는 대로 DataFrame.apply()를 사용할 수 있습니다.
df.apply()를 사용해 보세요. 만약 당신이 작은/중간 크기의 데이터 프레임을 가지고 있다면,
df['c2'] = df.apply(lambda x: 10 if x['c1'] == 'Value' else x['c1'], axis = 1)
그렇지 않으면, 큰 데이터 프레임이 있는 경우 위의 댓글에 언급된 슬라이싱 기술을 따르십시오.
큰 데이터셋이 있었는데 .loc[]이(가) 너무 오래 걸려서 벡터화된 방법을 찾았습니다.열을 논리 연산자로 설정하여 다음과 같이 작동할 수 있습니다.
file['Flag'] = (file['Claim_Amount'] > 0)
이것은 제가 원했던 부울을 제공하지만, 1을 곱해서 정수를 만들 수 있습니다.
언급URL : https://stackoverflow.com/questions/49161120/set-value-of-one-pandas-column-based-on-value-in-another-column
'programing' 카테고리의 다른 글
스프링 부트의 유효성 검사 중첩 (0) | 2023.07.25 |
---|---|
나가는 호스트/포트를 컨테이너에서 다른 포트로 매핑하는 방법 (0) | 2023.07.25 |
소수점 이하 1자리만 얻기 (0) | 2023.07.20 |
MARS(다중 활성 결과 집합)의 단점? (0) | 2023.07.20 |
Git 원격 URL을 변경한 후 원격에서 거부됨(허황한 업데이트는 허용되지 않음) (0) | 2023.07.20 |