[python] 열을 두 열로 나누는 방법은 무엇입니까?

하나의 열이있는 데이터 프레임이 있고 하나의 열 머리글을 ‘ fips'로하고 다른 열을 두 열로 나누고 싶습니다.'row'

내 데이터 프레임 df은 다음과 같습니다

          row
0    00000 UNITED STATES
1    01000 ALABAMA
2    01001 Autauga County, AL
3    01003 Baldwin County, AL
4    01005 Barbour County, AL

df.row.str[:]행 셀 분할의 목표를 달성 하는 데 사용하는 방법을 모르겠습니다 . 내가 사용할 수있는 df['fips'] = hello새 열을 추가하고 채 웁니다 hello. 어떤 아이디어?

         fips       row
0    00000 UNITED STATES
1    01000 ALABAMA 
2    01001 Autauga County, AL
3    01003 Baldwin County, AL
4    01005 Barbour County, AL



답변

더 좋은 방법이있을 수 있지만 여기에는 한 가지 방법이 있습니다.

                            row
    0       00000 UNITED STATES
    1             01000 ALABAMA
    2  01001 Autauga County, AL
    3  01003 Baldwin County, AL
    4  01005 Barbour County, AL
df = pd.DataFrame(df.row.str.split(' ',1).tolist(),
                                 columns = ['flips','row'])
   flips                 row
0  00000       UNITED STATES
1  01000             ALABAMA
2  01001  Autauga County, AL
3  01003  Baldwin County, AL
4  01005  Barbour County, AL


답변

TL; DR 버전 :

간단한 경우 :

  • 구분 기호가있는 텍스트 열이 있고 두 개의 열을 원합니다

가장 간단한 해결책은 다음과 같습니다.

df['A'], df['B'] = df['AB'].str.split(' ', 1).str

또는 다음을 사용하여 분할의 각 항목에 대해 하나의 열로 DataFrame을 만들 수 있습니다.

df['AB'].str.split(' ', 1, expand=True)

expand=True문자열에 균일하지 않은 스플릿 수가 None있고 결 측값을 바꾸려는 경우 사용해야 합니다.

두 경우 모두 .tolist()방법이 필요하지 않은 방법에 유의하십시오. 둘 다입니다 zip().

상세히:

Andy Hayden의 솔루션 은이 str.extract()방법 의 성능을 가장 잘 보여줍니다 .

그러나 알려진 구분 기호에 대한 간단한 분할 (예 : 대시로 나누기 또는 공백으로 나누기)의 경우이 .str.split()방법으로 충분합니다 1 . 문자열의 열 (Series)에서 작동하며 목록의 열 (Series)을 리턴합니다.

>>> import pandas as pd
>>> df = pd.DataFrame({'AB': ['A1-B1', 'A2-B2']})
>>> df

      AB
0  A1-B1
1  A2-B2
>>> df['AB_split'] = df['AB'].str.split('-')
>>> df

      AB  AB_split
0  A1-B1  [A1, B1]
1  A2-B2  [A2, B2]

1 : 처음 두 매개 변수가 무엇인지 확실하지 않은 경우 일반 Python 버전의 메서드에.str.split() 대한 문서를 권장합니다 .

그러나 당신은 어떻게 출발합니까 :

  • 두 요소로 구성된 목록을 포함하는 열

에:

  • 각각 목록의 각 요소를 포함하는 두 개의 열?

글쎄, 우리 .str는 열의 속성을 자세히 살펴볼 필요가있다 .

열의 각 요소를 문자열로 취급하는 메서드를 수집 한 다음 각 요소의 각 메서드를 가능한 한 효율적으로 적용하는 데 사용되는 마법의 개체입니다.

>>> upper_lower_df = pd.DataFrame({"U": ["A", "B", "C"]})
>>> upper_lower_df

   U
0  A
1  B
2  C
>>> upper_lower_df["L"] = upper_lower_df["U"].str.lower()
>>> upper_lower_df

   U  L
0  A  a
1  B  b
2  C  c

그러나 색인으로 문자열의 각 요소를 가져 오는 “인덱싱”인터페이스도 있습니다.

>>> df['AB'].str[0]

0    A
1    A
Name: AB, dtype: object

>>> df['AB'].str[1]

0    1
1    2
Name: AB, dtype: object

물론이 인덱싱 인터페이스는 .str인덱싱 할 수있는 한 인덱싱하는 각 요소가 실제로 문자열인지 여부를 실제로 신경 쓰지 않습니다.

>>> df['AB'].str.split('-', 1).str[0]

0    A1
1    A2
Name: AB, dtype: object

>>> df['AB'].str.split('-', 1).str[1]

0    B1
1    B2
Name: AB, dtype: object

그런 다음 파이썬 튜플의 iterables 압축 풀기를 활용하는 간단한 문제입니다.

>>> df['A'], df['B'] = df['AB'].str.split('-', 1).str
>>> df

      AB  AB_split   A   B
0  A1-B1  [A1, B1]  A1  B1
1  A2-B2  [A2, B2]  A2  B2

물론 문자열 열을 분할하여 DataFrame을 가져 오는 것은 매개 변수 .str.split()를 사용하여 메소드가 수행 할 수 있도록 매우 유용합니다 expand=True.

>>> df['AB'].str.split('-', 1, expand=True)

    0   1
0  A1  B1
1  A2  B2

따라서 우리가 원하는 것을 달성하는 또 다른 방법은 다음과 같습니다.

>>> df = df[['AB']]
>>> df

      AB
0  A1-B1
1  A2-B2

>>> df.join(df['AB'].str.split('-', 1, expand=True).rename(columns={0:'A', 1:'B'}))

      AB   A   B
0  A1-B1  A1  B1
1  A2-B2  A2  B2

expand=True버전은, 비록 이상, 튜플 풀고 방법을 통해 뚜렷한 장점이 있습니다. 튜플 포장 풀기는 길이가 다른 스플릿을 잘 처리하지 못합니다.

>>> df = pd.DataFrame({'AB': ['A1-B1', 'A2-B2', 'A3-B3-C3']})
>>> df
         AB
0     A1-B1
1     A2-B2
2  A3-B3-C3
>>> df['A'], df['B'], df['C'] = df['AB'].str.split('-')
Traceback (most recent call last):
  [...]    
ValueError: Length of values does not match length of index
>>> 

그러나 “분할”이 충분하지 않은 열에 expand=True배치하여 잘 처리합니다 None.

>>> df.join(
...     df['AB'].str.split('-', expand=True).rename(
...         columns={0:'A', 1:'B', 2:'C'}
...     )
... )
         AB   A   B     C
0     A1-B1  A1  B1  None
1     A2-B2  A2  B2  None
2  A3-B3-C3  A3  B3    C3


답변

정규식 패턴을 사용하여 다른 부분을 아주 깔끔하게 추출 할 수 있습니다 .

In [11]: df.row.str.extract('(?P<fips>\d{5})((?P<state>[A-Z ]*$)|(?P<county>.*?), (?P<state_code>[A-Z]{2}$))')
Out[11]: 
    fips                    1           state           county state_code
0  00000        UNITED STATES   UNITED STATES              NaN        NaN
1  01000              ALABAMA         ALABAMA              NaN        NaN
2  01001   Autauga County, AL             NaN   Autauga County         AL
3  01003   Baldwin County, AL             NaN   Baldwin County         AL
4  01005   Barbour County, AL             NaN   Barbour County         AL

[5 rows x 5 columns]

다소 긴 정규 표현식을 설명하려면 다음을 수행하십시오.

(?P<fips>\d{5})
  • 다섯 자리 숫자 ( \d)와 일치 하고 이름을 지정합니다 "fips".

다음 부분 :

((?P<state>[A-Z ]*$)|(?P<county>.*?), (?P<state_code>[A-Z]{2}$))

다음 |두 가지 중 하나를 수행합니다 .

(?P<state>[A-Z ]*$)
  • 임의의 수 *의 대문자 또는 공백 ( [A-Z ])과 일치 "state"하고 문자열 끝 ( $) 앞에 이름을 지정합니다 .

또는

(?P<county>.*?), (?P<state_code>[A-Z]{2}$))
  • 그 밖의 다른 항목 ( .*) 과 일치
  • 쉼표와 공백
  • state_code문자열 끝 ( $) 앞 의 두 자리 숫자와 일치합니다 .

예제에서 :
처음 두 행은 “state”(county 및 state_code 열에 NaN을 남기고)를, 마지막 3 개 행은 state_code (state 열에 NaN을 남겨)를 누르십시오.


답변

df[['fips', 'row']] = df['row'].str.split(' ', n=1, expand=True)


답변

새 데이터 프레임을 만들지 않거나 데이터 프레임에 분할하려는 열보다 많은 열이있는 경우 다음을 수행 할 수 있습니다.

df["flips"], df["row_name"] = zip(*df["row"].str.split().tolist())
del df["row"]  


답변

당신은 사용할 수 있습니다 str.split공백 (기본 구분) 및 매개 변수 expand=True에 대한 DataFrame새 열을 할당과 :

df = pd.DataFrame({'row': ['00000 UNITED STATES', '01000 ALABAMA',
                           '01001 Autauga County, AL', '01003 Baldwin County, AL',
                           '01005 Barbour County, AL']})
print (df)
                        row
0       00000 UNITED STATES
1             01000 ALABAMA
2  01001 Autauga County, AL
3  01003 Baldwin County, AL
4  01005 Barbour County, AL



df[['a','b']] = df['row'].str.split(n=1, expand=True)
print (df)
                        row      a                   b
0       00000 UNITED STATES  00000       UNITED STATES
1             01000 ALABAMA  01000             ALABAMA
2  01001 Autauga County, AL  01001  Autauga County, AL
3  01003 Baldwin County, AL  01003  Baldwin County, AL
4  01005 Barbour County, AL  01005  Barbour County, AL

필요한 경우 원본 열을 제거해야하는 경우 수정 DataFrame.pop

df[['a','b']] = df.pop('row').str.split(n=1, expand=True)
print (df)
       a                   b
0  00000       UNITED STATES
1  01000             ALABAMA
2  01001  Autauga County, AL
3  01003  Baldwin County, AL
4  01005  Barbour County, AL

같은 것 :

df[['a','b']] = df['row'].str.split(n=1, expand=True)
df = df.drop('row', axis=1)
print (df)

       a                   b
0  00000       UNITED STATES
1  01000             ALABAMA
2  01001  Autauga County, AL
3  01003  Baldwin County, AL
4  01005  Barbour County, AL

오류가 발생하면 :

#remove n=1 for split by all whitespaces
df[['a','b']] = df['row'].str.split(expand=True)

ValueError : 열은 키와 길이가 같아야합니다

당신은 확인 할 수 있으며 DataFrame2뿐만 아니라 4 열을 반환합니다 .

print (df['row'].str.split(expand=True))
       0        1        2     3
0  00000   UNITED   STATES  None
1  01000  ALABAMA     None  None
2  01001  Autauga  County,    AL
3  01003  Baldwin  County,    AL
4  01005  Barbour  County,    AL

그런 다음 솔루션은 다음과 같이 새로 추가 DataFrame됩니다 join.

df = pd.DataFrame({'row': ['00000 UNITED STATES', '01000 ALABAMA',
                           '01001 Autauga County, AL', '01003 Baldwin County, AL',
                           '01005 Barbour County, AL'],
                    'a':range(5)})
print (df)
   a                       row
0  0       00000 UNITED STATES
1  1             01000 ALABAMA
2  2  01001 Autauga County, AL
3  3  01003 Baldwin County, AL
4  4  01005 Barbour County, AL

df = df.join(df['row'].str.split(expand=True))
print (df)

   a                       row      0        1        2     3
0  0       00000 UNITED STATES  00000   UNITED   STATES  None
1  1             01000 ALABAMA  01000  ALABAMA     None  None
2  2  01001 Autauga County, AL  01001  Autauga  County,    AL
3  3  01003 Baldwin County, AL  01003  Baldwin  County,    AL
4  4  01005 Barbour County, AL  01005  Barbour  County,    AL

원래 열 제거 (다른 열이있는 경우) :

df = df.join(df.pop('row').str.split(expand=True))
print (df)
   a      0        1        2     3
0  0  00000   UNITED   STATES  None
1  1  01000  ALABAMA     None  None
2  2  01001  Autauga  County,    AL
3  3  01003  Baldwin  County,    AL
4  4  01005  Barbour  County,    AL   


답변

구분자를 기준으로 문자열을 두 개 이상의 열로 분할하려는 경우 ‘maximum splits’매개 변수를 생략 할 수 있습니다.
당신이 사용할 수있는:

df['column_name'].str.split('/', expand=True)

그러면 초기 문자열에 포함 된 최대 필드 수만큼 열이 자동으로 생성됩니다.