Транспонировать все строки в одном столбце данных в несколько столбцов в зависимости от определенных условий. - PullRequest
2 голосов
/ 30 мая 2019

Я хотел бы преобразовать один столбец данных в несколько столбцов в кадре данных на основе определенных значений / условий.

Найдите код для создания входного кадра данных

df1 = pd.DataFrame({'VARIABLE':['studyid',1,'age_interview', 65,'Gender','1.Male',
                            '2.Female',
                            'Ethnicity','1.Chinese','2.Indian','3.Malay']})

Данныевыглядит так, как показано ниже

enter image description here

Обратите внимание, что я не знаю заранее названия столбцов.Но обычно это следует за этим форматом.То, что я показал выше, представляет собой пример данных, и реальные данные могут иметь около 600-700 столбцов и данные, упорядоченные таким образом

Что я хотел бы сделать, это преобразовать значения, которые начинаются с нецифров (символов), какновые столбцы в датафрейме.Это может быть новый фрейм данных.

Я попытался записать цикл for, но не смог из-за ошибки ниже.Не могли бы вы помочь мне достичь этого результата.

for i in range(3,len(df1)):
#str(df1['VARIABLE'][i].contains('^\d'))
    if (df1['VARIABLE'][i].astype(str).contains('^\d') == True):

В вышеупомянутом цикле я пытался проверить, является ли первый символ цифрой, если да, а затем сохранить его как значение (например, 1,2, 3 и т. Д.) И если это персонаж (например, пол, этническая принадлежность и т. Д.), Создайте новый столбец.Но угадайте, что это неправильный и длительный подход

Например, в приведенном выше примере столбцы будут Studyid, age_interview, Gender, Ethnicity.

Окончательный результат будет выглядеть следующим образом

enter image description here

Не могли бы вы сообщить мне, если есть элегантный подход к этому?

Ответы [ 2 ]

1 голос
/ 30 мая 2019

Вы можете использовать groupby, чтобы сделать что-то вроде:

m=~df1['VARIABLE'].str[0].str.isdigit().fillna(True)
new_df=(pd.DataFrame(df1.groupby(m.cumsum()).VARIABLE.apply(list).
                                    values.tolist()).set_index(0).T)
print(new_df.rename_axis(None,axis=1))

  studyid age_interview    Gender  Ethnicity
1       1            65    1.Male  1.Chinese
2    None          None  2.Female   2.Indian
3    None          None      None    3.Malay

Пояснение : m - это вспомогательный ряд, который помогает разделить группы:

print(m.cumsum())
0     1
1     1
2     2
3     2
4     3
5     3
6     3
7     4
8     4
9     4
10    4

Затем мы группируем этот вспомогательный ряд и применяем список:

df1.groupby(m.cumsum()).VARIABLE.apply(list)
VARIABLE
1                                 [studyid, 1]
2                          [age_interview, 65]
3                   [Gender, 1.Male, 2.Female]
4    [Ethnicity, 1.Chinese, 2.Indian, 3.Malay]
Name: VARIABLE, dtype: object

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

1 голос
/ 30 мая 2019

Используйте itertools.groupby и затем создайте pd.DataFrame:

import pandas as pd
import itertools

l = ['studyid',1,'age_interview', 65,'Gender','1.Male',
                            '2.Female',
                            'Ethnicity','1.Chinese','2.Indian','3.Malay']
l = list(map(str, l))
grouped = [list(g) for k, g in itertools.groupby(l, key=lambda x:x[0].isnumeric())]
d = {k[0]: v for k,v in zip(grouped[::2],grouped[1::2])}

pd.DataFrame.from_dict(d, orient='index').T

Выход:

     Gender studyid age_interview  Ethnicity
0    1.Male       1            65  1.Chinese
1  2.Female    None          None   2.Indian
2      None    None          None    3.Malay
...