Как преобразовать неупорядоченный список в одну строку в pandas?

#python #pandas

#python #pandas

Вопрос:

У меня есть документ Word со списками, который я превращаю в фрейм данных pandas. Документ состоит из списков, что-то вроде:

Item1: abc

  • a = 2
  • bc = 01
  • Item2: abd

  • bd = 12
  • Item3: abt

    Я смог перенести эти данные в таблицу, подобную этой:

     d = {'item': ['item1','item1','item1','item2', 'item2', 'item3'], 'description': ['abc', 'a=2', 'bc=01', 'abd',' bd=12',  'abt']}
    df = pd.DataFrame(data=d)
    
      

    Но цель состоит в том, чтобы создать таблицу, подобную этой:

     d2 = {'item': ['item1', 'item2', 'item3'], 'description': ['abc', 'abd', 'abt'], 'labels': ["'a=2', 'bc=01'", 'bd=12', np.nan]}
    good_df = pd.DataFrame(data=d2)
      

    Изначально я планировал:

    1. установите столбец элемента в качестве индекса
    2. разделите фрейм данных на 2: один только со строками, у которых нет знака равенства, другой со строками, у которых есть знак равенства
    3. превратите строки в список
    4. добавить список в новый столбец в split-dataframe-1
     # split df
    split_df_1 = df[~df['labels'].str.contains("=")]
    split_df_2 = df[df['labels'].str.contains("=")]
    
    # set new index
    split_df_2 = df[df['labels'].str.contains("=")].set_index('item')
    
    split_df_2.loc('item1')
    
      

    и вот тут я застрял. Я получаю сообщение об ошибке «Нет оси с именем item1 для типа объектаDataFrame’>»

    Любая помощь с этой ошибкой или более чистый способ выполнения этой задачи были бы очень полезны.

    заранее спасибо

    Ответ №1:

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

     split_df_2.loc('item1')
    
    # Should be
    split_df_2.loc['item1']
      

    Это должно создать ваш предполагаемый результат. Сначала мы извлекаем строки «label», затем объединяем строки, которые имеют одинаковые item

     d = {'item': ['item1','item1','item1','item2', 'item2', 'item3'], 'description': ['abc', 'a=2', 'bc=01', 'abd',' bd=12',  'abt']}
    df = pd.DataFrame(data=d)
    
    label_mask = df["description"].str.contains("=")
    new_labels = (df.loc[label_mask, :]
                  .groupby("item")
                  .apply(lambda g: ", ".join(g["description"]))
                  
    print(new_labels)
    item
    item1    a=2, bc=01
    item2         bd=12
    dtype: object
      

    Теперь мы можем просто добавить его только в строки «описание», чтобы создать окончательный фрейм данных.

     new_df = (df.loc[~label_mask, :]      # Select the correct "description" rows
              .set_index("item")          # Change the index to be the item so our DataFrame aligns with our `new_labels` Series
              .assign(labels=new_labels)) # Add `new_labels` as its own column
    
    print(new_df)
          description      labels
    item                         
    item1         abc  a=2, bc=01
    item2         abd       bd=12
    item3         abt         NaN