Как разбить строки из нескольких пар ключ-значение в одном столбце данных на новый кадр данных в python? - PullRequest
1 голос
/ 17 мая 2019

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

Фрейм данных выглядит следующим образом:

In[1]:
print(df.tail())

Out[1]:
WK_VAL_PAIRS
166  {('sloth', 0.073), ('animal', 0.034), ('gift', 0.7843)}                              
167  {('dabbing', 0.0863), ('gift', 0.7843)}      
168  {('grandpa', 0.0156), ('funny', 1.3714), ('grandfather', 0.0015)}                                     
169  {('nerd', 0.0216)}
170  {('funny', 1.3714), ('pineapple', 0.0107)} 

В идеале новый фрейм данныхбудет выглядеть так:

0  |  sloth    |  0.073
1  |  animal   |  0.034
2  |  gift     |  0.07843
3  |  dabbing  |  0.0863
4  |  gift     |  0.7843
...
etc.

Мне удалось разделить пары ключ-значение из одной строки в информационный кадр, как показано ниже.Отсюда будет тривиально разбить пары на собственные столбцы.

In[2]:
def prep_text(row):
    string = row.replace('{', '')
    string = string.replace('}', '')
    string = string.replace('\',', '\':')
    string = string.replace(' ', '')
    string = string.replace(')', '')
    string = string.replace('(', '')
    string = string.replace('\'', '')
    return string

df['pairs'] = df['WK_VAL_PAIRS'].apply(prep_text)
dd = df['pairs'].iloc[166]
af = pd.DataFrame([dd.split(',') for x in dd.split('\n')])
af.transpose()

Out[2]:

0   sloth:0.073
1   animal:0.034
2   gift:0.7843
3   spirit:0.0065
4   fans:0.0093
5   funny:1.3714

Однако я упускаю шаг, чтобы применить это преобразование ко всему фрейму данных.Есть ли способ сделать это с помощью функции стиля .apply(), а не цикла for each.Какой самый питонический способ справиться с этим?

Любая помощь будет признательна.

Решение

С сильным намеком Криса ниже я смог найти адекватное решениедля моих нужд:

def prep_text(row):
    string = row.replace('\'', '')
    string = '"'+ string + '"'
    return string


kvp_df = pd.DataFrame(
                        re.findall(
                            '(\w+), (\d.\d+)', 
                            df['WK_VAL_PAIRS'].apply(prep_text).sum()
                        )
                    )

1 Ответ

2 голосов
/ 17 мая 2019

Попробуйте re.findall с pandas.DataFrame:

import pandas as pd
import re

s = pd.Series(["{(stepper, 0.0001), (bob, 0.0017), (habitual, 0.0), (line, 0.0097)}",
"{(pete, 0.01), (joe, 0.0019), (sleep, 0.0), (cline, 0.0099)}"])

pd.DataFrame(re.findall('(\w+), (\d.\d+)', s.sum()))

Выход:

          0       1
0   stepper  0.0001
1       bob  0.0017
2  habitual     0.0
3      line  0.0097
4      pete    0.01
5       joe  0.0019
6     sleep     0.0
7     cline  0.0099
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...