Как разделить столбец на два столбца?
у меня есть фрейм данных с одним столбцом, и я хотел бы разделить его на два столбца, с одним заголовком столбца как'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
8 ответов:
там может быть лучший способ, но это один из подходов:
In [34]: import pandas as pd In [35]: df Out[35]: row 0 00000 UNITED STATES 1 01000 ALABAMA 2 01001 Autauga County, AL 3 01003 Baldwin County, AL 4 01005 Barbour County, AL In [36]: df = pd.DataFrame(df.row.str.split(' ',1).tolist(), columns = ['flips','row']) In [37]: df Out[37]: 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или вы можете создать создать фрейм данных с одним столбцом для каждой записи разделения автоматически с:
df['AB'].str.split(' ', 1, expand=True)обратите внимание, как, в любом случае
.tolist()метод не нужен. Так же как иzip().In деталь:
решение Энди Хейдена является самым превосходным в демонстрации силы
str.extract()метод.но для простого разбиения по известному разделителю (например, разбиение на тире или разбиение на пробелы),
.str.split()способ достаточно1. Он работает со столбцом (серией) строк и возвращает столбец (серию) списков:>>> 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: Если вы не знаете, какие первые два параметра
.str.split()do, Я рекомендую документы для простая версия Python метода.но как вы идете из:
- столбец, содержащий двухэлементные списки
to:
- два столбца, каждый из которых содержит соответствующий элемент списков?
Ну, нам нужно поближе взглянуть на
.strатрибут столбца.это a магический объект, который используется для сбора методов, которые обрабатывают каждый элемент в столбце как строку, а затем применяют соответствующий метод в каждом элементе как можно эффективнее:
>>> 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тогда, это простой вопрос использования кортежа Python распаковки итераций, чтобы сделать
>>> 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конечно, получение фрейма данных из разбиения столбца строк настолько полезно, что
.str.split()метод может сделать это за вас с :>>> 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
вы можете экстракт различные части довольно аккуратно, используя шаблон регулярного выражения:
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до конца строки ($).пример:
обратите внимание, что первые две строки попали в "состояние" (оставив NaN в графстве и state_code столбцы), в то время как последние три попали в графство, state_code (оставив NaN в столбце state).
Если вы не хотите создавать новый фрейм данных, или если ваш фрейм данных имеет больше столбцов, чем только те, которые вы хотите разделить, вы можете:
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.popdf[['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: столбцы должны быть той же длины, что и key
вы можете проверить и его вернуться 4 колонки
DataFrame, а не только 2: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тогда решение добавить новый
DataFramebyjoin: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)это автоматически создаст столько столбцов, сколько максимальное количество полей, включенных в любую из ваших начальных строк.
Я предпочитаю экспортировать соответствующие серии панд (т. е. столбцы, которые мне нужны), используя применить функция для разделения содержимого столбца на несколько серий, а затем вступить созданные столбцы в существующий фрейм данных. Конечно, исходный столбец должен быть удален.
например
col1 = df["<col_name>"].apply(<function>) col2 = ... df = df.join(col1.to_frame(name="<name1>")) df = df.join(col2.toframe(name="<name2>")) df = df.drop(["<col_name>"], axis=1)чтобы разделить два слова строки функция должна быть что-то вроде этого:
lambda x: x.split(" ")[0] # for the first element lambda x: x.split(" ")[-1] # for the last element
Comments