Nano Hash - криптовалюты, майнинг, программирование

Как разбить столбец строки фрейма данных на два столбца?

У меня есть фрейм данных с одним (строковым) столбцом, и я хотел бы разделить его на два (строковых) столбца, с одним заголовком столбца как '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
07.02.2013

  • как вы загружали свои данные в панды? Вы можете загрузить данные в желаемом формате, используя read_table() или read_fwf() 08.02.2013
  • Как разделить столбец имеет разные ответы в зависимости от того, является ли столбец строкой, списком или чем-то еще, а также от того, какой формат (например, «форматированная строка», например адрес, для которого вам может потребоваться regex. Здесь у вас есть строковый столбец с форматом фиксированной ширины (ZZZZZ placename ...), поэтому мы знаем, что почтовый индекс - это символы 0: 4, а имя - символы 6: 29.10.2020

Ответы:


1

Возможно, есть лучший способ, но вот один из подходов:

                            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 = ['fips','row'])
   fips                 row
0  00000       UNITED STATES
1  01000             ALABAMA
2  01001  Autauga County, AL
3  01003  Baldwin County, AL
4  01005  Barbour County, AL
07.02.2013
  • Имейте в виду, что .tolist () удалит все имеющиеся у вас индексы, поэтому ваш новый Dataframe будет переиндексирован с 0 (это не имеет значения в вашем конкретном случае). 27.03.2013
  • @Crashthatch - опять же, вы можете просто добавить index = df.index, и все будет хорошо. 27.03.2013
  • что делать, если одну ячейку нельзя разделить? 30.10.2018
  • @Nisba: если какая-либо ячейка не может быть разделена (например, в этом случае строка не содержит пробела), она все равно будет работать, но одна часть разделения будет пустой. Другие ситуации произойдут, если у вас есть смешанные типы в столбце, по крайней мере, в одной ячейке, содержащей любой числовой тип. Затем метод split возвращает NaN, а метод tolist вернет это значение как есть (NaN), что приведет к ValueError (для решения этой проблемы вы можете преобразовать его в строковый тип перед разделением). Я рекомендую вам попробовать это самостоятельно, это лучший способ обучения :-) 18.12.2019
  • @techkuz: Вы уверены, что в вашем df есть заголовок столбца row? Вы можете подумать, что это какой-то атрибут DataFrame, но совершенно ясно, что это имя столбца. Вам решать, как создавать и определять заголовки столбцов, поэтому, если вы используете другой, используйте его (например, df.my_column_name.split(...)). 18.12.2019

  • 2

    TL; Версия DR:

    Для простого случая:

    • У меня есть текстовый столбец с разделителем, и мне нужны два столбца

    Самое простое решение:

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

    Вы должны использовать expand=True, если ваши строки имеют неоднородное количество разбиений и вы хотите None заменить отсутствующие значения.

    Обратите внимание, что в любом случае метод .tolist() не нужен. Ни zip().

    В деталях:

    Решение Энди Хайдена лучше всего демонстрирует возможности _ 6_.

    Но для простого разделения по известному разделителю (например, разделение тире или разделение пробелами) _ 7_ достаточно 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(), я рекомендую документы для простая версия метода для Python.

    Но как выйти из:

    • столбец, содержащий двухэлементные списки

    to:

    • два столбца, каждый из которых содержит соответствующий элемент списков?

    Что ж, нам нужно внимательнее взглянуть на атрибут .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
    

    Затем нужно просто воспользоваться распаковкой кортежей 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
    

    Конечно, получение 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
    
    06.09.2016
  • df ['A'], df ['B'] = df ['AB']. str.split ('', 1) .str Что означает '1' в split ('', 1)? 30.03.2017
  • @Hariprasad, это максимальное количество разбиений. Я добавил ссылку на документы для версии Python .split() метод, который объясняет первые два параметра лучше, чем документы Pandas. 30.03.2017
  • pandas 1.0.0 сообщает FutureWarning: итерация по столбцам по символам будет устаревшей в будущих выпусках. 05.02.2020
  • Это работает под Python 1.0.1. df.join(df['AB'].str.split('-', 1, expand=True).rename(columns={0:'A', 1:'B'})) 07.03.2020
  • Потрясающие. Боролся с этим и создал код улитки 06.10.2020
  • @MartienLubberink Вместо этого вы можете назначить суб-срез DataFrame: df[['A', 'B']] = df['AB'].str.split('-', n=1, expand=True) 29.10.2020
  • Это здорово, но как разделить, если у вас есть две разные области разделения? Короче говоря: я читаю SQL и хочу взять оператор FROM и разделить его на базу данных, схему, таблицу, псевдоним. База данных, схема и таблица просты - я разделяю точку / точку. Но псевдоним? Иногда это могло быть просто пространство, а иногда люди вставляли AS. Что ты предлагаешь? 29.06.2021
  • @DataGirl, для этого я бы предложил _1 _ с правильно написанным регулярным выражением. 02.07.2021
  • @LeoRochael - спасибо! Я попробую! :) 02.07.2021

  • 3

    Вы можете извлечь различные части довольно аккуратно, используя регулярное выражение. шаблон:

    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" перед концом строки ($),

    or

    (?P<county>.*?), (?P<state_code>[A-Z]{2}$))
    
    • соответствует чему-либо еще (.*), тогда
    • запятая и пробел, затем
    • соответствует двум цифрам state_code перед концом строки ($).

    В примере:
    Обратите внимание, что первые две строки попадают в "состояние" (оставляя NaN в столбцах county и state_code), в то время как последние три попадают в county, state_code (оставляя NaN в столбце состояния).

    23.01.2014
  • Это определенно лучшее решение, но оно может показаться немного сложным для некоторых с очень обширным регулярным выражением. Почему бы не сделать это как часть 2 и не сделать часть 1 только с фипами и столбцами строк? 12.04.2016
  • @josh, это хороший момент, хотя отдельные части регулярного выражения легко понять, длинное регулярное выражение может быстро усложниться. Я добавил пояснения для будущих читателей! (Мне также пришлось обновить ссылку на документы, которые объясняют синтаксис (?P<label>...)! Я понятия не имею, почему я выбрал более сложное регулярное выражение, очевидно, что простое могло работать хмммм 13.04.2016
  • Выглядит намного дружелюбнее. Я рад, что вы это сделали, потому что это заставило меня посмотреть документацию, чтобы понять <group_name>. Теперь я знаю, что это делает мой код очень лаконичным. 13.04.2016

  • 4

    Вы можете использовать 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: столбцы должны быть той же длины, что и ключ

    Вы можете проверить, и он вернет 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
    

    Затем к решению добавляется новый 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   
    
    21.04.2018
  • Если есть два таких столбца, которые необходимо разделить, возвращается: ValueError: columns overlap but no suffix specified: 20.07.2020

  • 5

    Если вы не хотите создавать новый фрейм данных или если в вашем фрейме данных больше столбцов, чем только те, которые вы хотите разделить, вы можете:

    df["flips"], df["row_name"] = zip(*df["row"].str.split().tolist())
    del df["row"]  
    
    29.09.2015
  • Я получаю zip argument #1 must support iteration ошибку, python 2.7 03.08.2016

  • 6

    Если вы хотите разбить строку на более чем два столбца на основе разделителя, вы можете опустить параметр «максимальное количество разделений».
    Вы можете использовать:

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

    Это автоматически создаст столько столбцов, сколько максимальное количество полей, включенных в любую из ваших исходных строк.

    15.01.2018

    7

    Удивлен, что еще не видел этого. Если вам нужно всего два разделения, я настоятельно рекомендую. . .

    Series.str.partition

    partition выполняет одно разделение на разделителе и, как правило, достаточно производительно.

    df['row'].str.partition(' ')[[0, 2]]
    
           0                   2
    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.partition(' ')[[0, 2]].rename({0: 'fips', 2: 'row'}, axis=1)
    
        fips                 row
    0  00000       UNITED STATES
    1  01000             ALABAMA
    2  01001  Autauga County, AL
    3  01003  Baldwin County, AL
    4  01005  Barbour County, AL
    

    Если вам нужно присоединить это обратно к оригиналу, используйте join или concat:

    df.join(df['row'].str.partition(' ')[[0, 2]])
    

    pd.concat([df, df['row'].str.partition(' ')[[0, 2]]], axis=1)
    
                            row      0                   2
    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
    
    22.01.2019

    8

    Используйте df.assign для создания нового df. См. https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.assign.html

    split = df_selected['name'].str.split(',', 1, expand=True)
    df_split = df_selected.assign(first_name=split[0], last_name=split[1])
    df_split.drop('name', 1, inplace=True)
    

    Или в виде цепочки методов:

    df_split = (df_selected
                .assign(list_col=lambda df: df['name'].str.split(',', 1, expand=False),
                        first_name=lambda df: df.list_col.str[0],
                        last_name=lambda df: df.list_col.str[1])
                .drop(columns=['list_col']))
    
    31.10.2019

    9

    Я предпочитаю экспортировать соответствующие серии панд (то есть столбцы, которые мне нужны), используя функцию применить, чтобы разделить содержимое столбца на несколько серий, а затем присоединить сгенерированные столбцы к существующим DataFrame. Конечно, столбец с исходным кодом следует удалить.

    e.g.

     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
    
    03.06.2018

    10

    Я увидел, что никто не использовал метод нарезки, поэтому я положил сюда свои 2 цента.

    df["<col_name>"].str.slice(stop=5)
    df["<col_name>"].str.slice(start=6)
    

    Этот метод создаст два новых столбца.

    03.07.2019
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..


    © 2024 nano-hash.ru, Nano Hash - криптовалюты, майнинг, программирование