Python 根据特定条件将dataframe的一列中的所有行转置为多列

Python 根据特定条件将dataframe的一列中的所有行转置为多列,python,python-3.x,pandas,dataframe,transpose,Python,Python 3.x,Pandas,Dataframe,Transpose,我想根据某些值/条件将dataframe中的一列数据转换为多列 请查找生成输入数据帧的代码 df1 = pd.DataFrame({'VARIABLE':['studyid',1,'age_interview', 65,'Gender','1.Male', '2.Female', 'Ethnicity','1.Chinese','2.Indian','3.Malay']}) 数据如下

我想根据某些值/条件将dataframe中的一列数据转换为多列

请查找生成输入数据帧的代码

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

请注意,我可能事先不知道列名。但它通常遵循这种格式。我上面展示的是一个示例数据,实际数据可能有600-700列,数据以这种方式排列

我想做的是将以非数字(字符)开头的值转换为dataframe中的新列。它可以是一个新的数据帧

我试图写一个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、年龄、访谈、性别、种族

最终输出如下所示


你能告诉我是否有一个优雅的方法来做到这一点吗

使用
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

您可以使用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))

解释
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
此时,我们将每个组作为一个列表,列名称作为第一个条目。
因此,我们用它创建了一个数据帧,并将第一列设置为索引和转置,以获得所需的输出。

非常感谢您的响应。我看到您已经创建了一个列表。但在实时情况下,我可能有600多列和相应的数据。所以我想知道我是否能够在那个时候手动创建这个列表time@SELVA我猜你的意思是你有一个有600个键和值的dict?在这种情况下,您可以始终迭代dict。您的列是否共享列名称,因此最终需要连接?我的实时输入文件如上图所示,是一个包含一列数据(变量列)的excel工作表。但是,我必须对其进行处理,以识别列名(性别、种族等),并将其创建为新列,并输入“预期输出”部分Q1)中所示的值。您能否帮助我了解此行的作用“df1.groupby(m.cumsum()).VARIABLE.apply(list)”。我知道它根据它们的累计值将这些值分组在一起。此行的输出是一个系列数据类型。我们是否应用“df1.groupby(m.cumsum()).VARIABLE.apply(list).values.tolist())”将其转换为dataframe.Sure。不worries@SELVA最新解释。感谢您的耐心,是的,因为列表的长度不同,所以我们会创建一个数据框,并保留缺失的值。您能帮助我吗?你能帮我做这个吗?
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