programing

다른 열의 값을 기준으로 한 Pandas 열의 값 설정

linuxpc 2023. 7. 25. 20:41
반응형

다른 열의 값을 기준으로 한 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

반응형