Pandas dataframe: как превратить одну строку в отдельные строки на основе значения столбца с меткой

1

Я создаю классификацию настроений на основе сущности для анализа новостей в новостях. Для каждой статьи новостей, возможно, будет идентифицировано несколько валют. Но я борюсь с тем, как можно превратить одну строку (например, {'USD':1, "JPY":-1} в соответствии с существующей меткой человека) в отдельные строки.

Образец данных:

       sentiment                                               text
0   USD:1,CNY:-1  US economy is improving while China is struggling
1  USD:-1, JPY:1    Unemployment is high for US while low for Japan

И хотел бы преобразовать в несколько строк следующим образом:

  currency sentiment                                               text
0      USD         1  US economy is improving while China is struggling
1      CNY        -1  US economy is improving while China is struggling
2      USD        -1    Unemployment is high for US while low for Japan
3      JPY         1    Unemployment is high for US while low for Japan

Большое спасибо за вашу помощь

  • 0
    Что такое тип данных "настроение"?
  • 0
    Строка как и сейчас, но может быть легко превращена в целое число
Теги:
pandas

5 ответов

0

Это должно работать

s = df['sentiment'].str.split(',').apply(pd.Series, 1).stack()
s.index = s.index.droplevel(-1)
s.name = 'sentiment'
del df['sentiment']
df = df.join(s)

df['currency'] = df.sentiment.apply(lambda x: x.split(':')[0])
df['sentiment'] = df.sentiment.apply(lambda x: int(x.split(':')[-1]))
0

Вы можете построить новый фрейм данных, привязать и повторить значения, если это необходимо.

import numpy as np
from itertools import chain

df = pd.DataFrame({'sentiment': ['USD:1,CNY:-1', 'USD:-1, JPY:1'],
                   'text': ['US economy is improving while China is struggling',
                            'Unemployment is high for US while low for Japan']})

# remove whitespace and split by ','
df['sentiment'] = df['sentiment'].str.replace(' ', '').str.split(',')

# construct expanded dataframe
res = pd.DataFrame({'sentiment': list(chain.from_iterable(df['sentiment'])),
                    'text': np.repeat(df['text'], df['sentiment'].map(len))})

# split sentiment series into currency and value components
res[['currency', 'sentiment']] = res.pop('sentiment').str.split(':', expand=True)
res['sentiment'] = res['sentiment'].astype(int)

Результат:

print(res)

                                                text currency sentiment
0  US economy is improving while China is struggling      USD         1
0  US economy is improving while China is struggling      CNY        -1
1    Unemployment is high for US while low for Japan      USD        -1
1    Unemployment is high for US while low for Japan      JPY         1
0

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

df1 = df1.merge(df1.sentiment.str.split(',',expand=True),left_index=True,right_index=True,how='outer')
df1.drop('sentiment',axis=1,inplace=True)
df1 = df1.melt('text')
df1[['currency','sentiment']] = df1.value.str.split(':',expand=True)
df1.drop(['variable','value'],axis=1,inplace=True)

Выход:

                      text                               currency   sentiment
0   US economy is improving while China is struggling     CNY   -1
1   Unemployment is high for US while low for Japan       JPY   1
2   US economy is improving while China is struggling     USD   1
3   Unemployment is high for US while low for Japan       USD   -1
0

Вы можете разделить sentiment col ,|: затем развернуть & stack

Затем используйте pd.reindex & pd.index.repeat для повторения text столбца на основе len split.

# Split the col on both , and : then stack.
s = df['sentiment'].str.split(',|:',expand=True).stack()

# Reindex and repeat cols on len of split and reset index.
df1 = df.reindex(df.index.repeat(df['sentiment'].fillna("").str.split(',').apply(len))) 
df1 = df1.reset_index(drop=True)

df1['currency'] = s[::2].reset_index(drop=True)
df1['sentiment'] = s[1::2].reset_index(drop=True)

print (df1.sort_index(axis=1))

Выход:

    currency  sentiment              text
0    USD         1        US economy is improving while China is struggling
1    CNY        -1        US economy is improving while China is struggling
2    USD        -1        Unemployment is high for US while low for Japan
3    JPY         1        Unemployment is high for US while low for Japan
0

Попробуйте выполнить мою реализацию (не мутирует исходный DataFrame):

import re
def parse_sentiment(sentiment):
    currencies = sentiment.split(',')
    result = dict()
    # remove spaces from currencies
    for c in currencies:
        temp = re.sub(r'[\s]*', '', c).split(':')
        result[temp[0]] = int(temp[1])
    return result


i = 0
rows = []
for s in df.loc[:, 'sentiment']:
    temp = parse_sentiment(s)
    for t in temp:
        temp_row = [t, temp[t], df.iloc[i]['text']]
        rows.append(temp_row)
    i += 1

df_new = pd.DataFrame(rows, columns=['currency', 'sentiment', 'text'])

Ещё вопросы

Сообщество Overcoder
Наверх
Меню