我遇到了这个问题,我有一个数据帧,看起来像下面(最后3列中的值通常是4-5个字母数字代码).

import pandas as pd

data = {'ID':['P39','S32'],
        'Name':['Pipe','Screw'],
        'Col3':['Test1, Test2, Test3','Test6, Test7'],
        'Col4':['','Test8, Test9'],
        'Col5':['Test4, Test5','Test10, Test11, Test12, Test13']
       }

df = pd.DataFrame(data)
ID Name Col3 Col4 Col5
0 P39 Pipe Test1, Test2, Test3 Test4, Test5
1 S32 Screw Test6, Test7 Test8, Test9 Test10, Test11, Test12, Test13

我想扩展这个数据帧,或者基于每行最后3列中的值创建一个新的数据帧.我想根据最后三行中以逗号分隔的最大值创建更多行.然后,我希望在所有展开的行中保持前2列相同.但是我想用原始列中的一个值填充扩展行中的最后3列.

在上面的示例中,第一行表示我总共需要3行(Col3在3个值时最多),第二行表示我总共需要4行(Col5在4个值时最多).所需输出应符合以下要求:

ID Name Col3 Col4 Col5
0 P39 Pipe Test1 Test4
1 P39 Pipe Test2 Test5
2 P39 Pipe Test3
3 S32 Screw Test6 Test8 Test10
4 S32 Screw Test7 Test9 Test11
5 S32 Screw Test12
6 S32 Screw Test13

我首先找到了一种计算所需行数的方法.我还想把这些值附加到同一个循环中的新数据帧中.尽管如此,我不知道如何将最后3列中的值分开,并将它们逐个追加到行中.我知道str.split()对于将值放入列表非常有用.我唯一的 idea 是,如果我需要分别遍历每一列并将其附加到正确的行中,但我不知道如何做到这一点.

output1 = pd.DataFrame(
    columns = ['ID', 'Name', 'Col3', 'Col4', 'Col5'])

for index, row in df.iterrows():
    
    output2 = pd.DataFrame(
        columns = ['ID', 'Name', 'Col3', 'Col4', 'Col5'])

    col3counter = df.iloc[index, 2].count(',')
    col4counter = df.iloc[index, 3].count(',')
    col5counter = df.iloc[index, 4].count(',')
    
    numofnewcols = max(col3counter, col4counter, col5counter) + 1

    iter1 = df.iloc[index, 2].split(', ')
    iter2 = df.iloc[index, 3].split(', ')
    iter3 = df.iloc[index, 4].split(', ')

    #for q in iter1
        #output2.iloc[ , 2] = 
    

    output1 = pd.concat([output1, output2], ignore_index=True)
    del output2

推荐答案

有点棘手,但它应该使用melt来平整数据帧,然后使用pivot_table来reshape 数据帧:

out = (df.reset_index().melt(['ID', 'Name', 'index'], var_name='col', value_name='val')
         .assign(val=lambda x: x['val'].str.split(', ')).explode('val')
         .assign(row=lambda x: x.groupby(['index', 'col']).cumcount())
         .pivot_table('val', ['index', 'row', 'ID', 'Name'], 'col', aggfunc='first')
         .droplevel(['index', 'row']).reset_index().rename_axis(columns=None).fillna(''))

输出:

ID Name Col3 Col4 Col5
0 P39 Pipe Test1 Test4
1 P39 Pipe Test2 Test5
2 P39 Pipe Test3
3 S32 Screw Test6 Test8 Test10
4 S32 Screw Test7 Test9 Test11
5 S32 Screw Test12
6 S32 Screw Test13

Python相关问答推荐

海运图:调整行和列标签

OR—Tools中CP—SAT求解器的IntVar设置值

无法使用DBFS File API路径附加到CSV In Datricks(OSError Errno 95操作不支持)

在Python argparse包中添加formatter_class MetavarTypeHelpFormatter时, - help不再工作""""

Pandas—在数据透视表中占总数的百分比

如何合并两个列表,并获得每个索引值最高的列表名称?

Python 3试图访问在线程调用中实例化的类的对象

如何合并具有相同元素的 torch 矩阵的行?

删除特定列后的所有列

为什么dict. items()可以快速查找?

如何在SQLAlchemy + Alembic中定义一个"Index()",在基表中的列上

Polars表达式无法访问中间列创建表达式

我怎么才能用拉夫分拣呢?

有了Gekko,可以创建子模型或将模型合并在一起吗?

为什么我只用exec()函数运行了一次文件,而Python却运行了两次?

递归链表反转与打印语句挂起

按列表分组到新列中

为什么在安装了64位Python的64位Windows 10上以32位运行?

401使用有效的OAuth令牌向Google Apps脚本Web App发出POST请求时出现未经授权的错误(";

`Convert_time_zone`函数用于根据为极点中的每一行指定的时区检索值