Как преобразовать данные CSV из широкого формата в длинный набор данных, используя Python - PullRequest
1 голос
/ 11 февраля 2020

Мне нужно выполнить приведенное ниже преобразование данных для произвольного числа «элементов», используя Python. Первые два столбца всегда одинаковы, тогда могут быть тысячи столбцов "itemN", и я хотел бы, чтобы все действительные значения были в новом отдельном столбце.

Я попытался использовать pandas. wide_to_long, но, насколько мне известно, я бы поместил новое имя в транспонированную таблицу, которая не сработала бы, если бы количество элементов могло измениться.

type   rid          item1 item2 item3
apple  [81]          1.1   1.1   1.1 
orange [82]          2.2   2.2   2.2 
banana [41,42,43,52] 3.3   3.3   3.3 
kiwi   [90,95]       4.4   4.4   4.4 

на

type   rid             gid   value
apple  [81]           item1   1.1 
apple  [81]           item2   1.1 
apple  [81]           item3   1.1 
orange [82]           item1   2.2 
orange [82]           item2   2.2 
orange [82]           item3   2.2 
banana [41,42,43,52]  item1   3.3 
banana [41,42,43,52]  item2   3.3 
banana [41,42,43,52]  item3   3.3 
kiwi   [90,95]        item1   4.4 
kiwi   [90,95]        item2   4.4 
kiwi   [90,95]        item3   4.4

Итак До сих пор я пытался использовать double для l oop и нарезку индекса с массивами numpy и использовать pandas .wide_to_long.

a = np.array([['apple'  ,tuple([81]) ,1.1 ,1.1 ,1.1] ,['orange' ,tuple([82]) ,2.2 ,2.2 ,2.2],['banana' ,tuple([41,42,43,52]) ,3.3 ,3.3 ,3.3],['kiwi' ,tuple([90,95]) ,4.4 ,4.4 ,4.4]])
names = ['type' ,'rid' ,'item1' ,'item2' ,'item3']
df = pd.DataFrame(a,columns=names)

Ответы [ 3 ]

0 голосов
/ 11 февраля 2020

Вы можете поместить первые 2 столбца в индекс, сложить результирующий кадр данных и затем сбросить индекс:

df.set_index(['type', 'rid']).stack().reset_index()

дает:

      type            rid level_2    0
0    apple           [81]   item1  1.1
1    apple           [81]   item2  1.1
2    apple           [81]   item3  1.1
3   orange           [82]   item1  2.2
4   orange           [82]   item2  2.2
5   orange           [82]   item3  2.2
6   banana  [41,42,43,52]   item1  3.3
7   banana  [41,42,43,52]   item2  3.3
8   banana  [41,42,43,52]   item3  3.3
9     kiwi        [90,95]   item1  4.4
10    kiwi        [90,95]   item2  4.4
11    kiwi        [90,95]   item3  4.4

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

df.set_index(['type', 'rid']).stack().reset_index().rename(columns={'level_2': 'gid',
                                   0: 'value'})

дает ожидаемый кадр данных.

0 голосов
/ 11 февраля 2020

Простым ответом на go будет использование функции pandas .melt () .

df = df.melt(id_vars=['type', 'rid'], value_vars=['item1', 'item2', 'item3'])

Вывод: enter image description here

0 голосов
/ 11 февраля 2020

Это похоже на работу для DataFrame.explode (pandas 0,25 +).

# Build a DataFrame identical to the first example data you provided
d = {'type': {0: 'apple', 1: 'orange', 2: 'banana', 3: 'kiwi'},
     'rid': {0: [81], 1: [82], 2: [41, 42, 43, 52], 3: [90, 95]},
     'item1': {0: 1.1, 1: 2.2, 2: 3.3, 3: 4.4},
     'item2': {0: 1.1, 1: 2.2, 2: 3.3, 3: 4.4},
     'item3': {0: 1.1, 1: 2.2, 2: 3.3, 3: 4.4}})
df = pd.DataFrame(d)

# Explode the 'rid' column and reset to default integer index
df.explode('rid').reset_index(drop=True)

     type rid  item1  item2  item3
0   apple  81    1.1    1.1    1.1
1  orange  82    2.2    2.2    2.2
2  banana  41    3.3    3.3    3.3
3  banana  42    3.3    3.3    3.3
4  banana  43    3.3    3.3    3.3
5  banana  52    3.3    3.3    3.3
6    kiwi  90    4.4    4.4    4.4
7    kiwi  95    4.4    4.4    4.4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...