Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将数据帧中具有多个值的单元格转换为多行_Python_Pandas - Fatal编程技术网

Python 将数据帧中具有多个值的单元格转换为多行

Python 将数据帧中具有多个值的单元格转换为多行,python,pandas,Python,Pandas,我的数据如下: Name test1 test2 Count Emp1 X,Y A 1 Emp2 X A,B,C 2 Emp3 Z C 3 我正在使用下面的代码将具有多个值的test1单元格拆分为单独的行。但是,我不确定如何拆分Test2列 df2 = df.test1.str.split(',').apply(pd.Series) df2.index

我的数据如下:

Name    test1     test2      Count
Emp1    X,Y        A           1
Emp2    X          A,B,C       2
Emp3    Z          C           3
我正在使用下面的代码将具有多个值的test1单元格拆分为单独的行。但是,我不确定如何拆分Test2

df2 = df.test1.str.split(',').apply(pd.Series)
df2.index = df.set_index(['Name', 'count']).index
df2.stack().reset_index(['Name', 'count'])
df2
输出为:

Name    test1   Count
Emp1    X        1
Emp1    Y        1
Emp2    X        2
Emp2    X        2
Emp2    X        2
Emp2    Z        3
我正在尝试拆分test1test2,以便实现以下输出:

Name    test1    test2  Count
Emp1    X          A      1
Emp1    Y          A      1
Emp2    X          A      2
Emp2    X          B      2
Emp2    X          C      2
Emp2    Z          C      3

有人能帮忙吗?

我只是修复你的代码,因为我不推荐你卸载数据帧的方法,你可以在这里检查,有多种好方法

df2 = df.test1.str.split(',').apply(pd.Series)
df2.index = df.set_index(['Name', 'Count']).index
df2=df2.stack().reset_index(['Name', 'Count'])
df3 = df.test2.str.split(',').apply(pd.Series)
df3.index = df.set_index(['Name', 'Count']).index
df3=df3.stack().reset_index(['Name', 'Count'])
只需在这里进行
merge

我认为适应这个问题并不是那么简单,所以我将提出一个解决方案

您可以创建一个函数,该函数采用
df
、一个要展开的列和该列的分隔符,并根据需要多次进行链调用

def expand(df, col, sep=','):
    r = df[col].str.split(sep)
    d = {c: df[c].values.repeat(r.str.len(), axis=0) for c in df.columns}
    d[col] = [i for sub in r for i in sub]
    return pd.DataFrame(d)

expand(expand(df, 'test1'), 'test2')

    Name    test1   test2   Count
0   Emp1    X       A       1
1   Emp1    Y       A       1
2   Emp2    X       A       2
3   Emp2    X       B       2
4   Emp2    X       C       2
5   Emp3    Z       C       3
假设你有一个

df['test3'] = ['X1|X2|X3', 'X4', 'X5']
以致

>>> print(df)

    Name    test1   test2   Count   test3
0   Emp1    X,Y     A       1       X1|X2|X3
1   Emp2    X       A,B,C   2       X4
2   Emp3    Z       C       3       X5
那么

如果您认为列的大小可能会大幅增加,则可以定义一个函数
expand_all
,以避免出现类似
expand(expand(expand)(expand(…..)!)))
的情况。例如:

def expand_all(df, cols, seps):
    ret = df
    for c,s in zip(cols,seps): ret = expand(ret,c,s)
    return ret

>>> expand_all(df, ['test1', 'test2', 'test3'], [',', ',', '|'])

    Name    test1   test2   Count   test3
0   Emp1    X       A       1       X1
1   Emp1    X       A       1       X2
2   Emp1    X       A       1       X3
3   Emp1    Y       A       1       X1
4   Emp1    Y       A       1       X2
5   Emp1    Y       A       1       X3
6   Emp2    X       A       2       X4
7   Emp2    X       B       2       X4
8   Emp2    X       C       2       X4
9   Emp3    Z       C       3       X5
或无论如何合适;)


详情:

>>> expand(df, 'test1')

    Name    test1   test2   Count
0   Emp1    X       A       1
1   Emp1    Y       A       1
2   Emp2    X       A,B,C   2
3   Emp3    Z       C       3

>>> expand(df, 'test2')

    Name    test1   test2   Count
0   Emp1    X,Y     A       1
1   Emp2    X       A       2
2   Emp2    X       B       2
3   Emp2    X       C       2
4   Emp3    Z       C       3

>>> expand(expand(df, 'test2'), 'test1') 

    Name    test1   test2   Count
0   Emp1    X       A       1
1   Emp1    Y       A       1
2   Emp2    X       A       2
3   Emp2    X       B       2
4   Emp2    X       C       2
5   Emp3    Z       C       3


>>> expand(expand(df, 'test2'), 'test1').eq(expand(expand(df, 'test1'), 'test2')).all()

Name     True
test1    True
test2    True
Count    True
dtype: bool
理解力
@Mahesh我试图使我的解决方案尽可能普遍化。稍后查看,看看是否有帮助;)@RafaelC我尝试了你建议的expand_all函数,我发现它正在扩展已经扩展的列。这导致了价值观的重复
def expand_all(df, cols, seps):
    ret = df
    for c,s in zip(cols,seps): ret = expand(ret,c,s)
    return ret

>>> expand_all(df, ['test1', 'test2', 'test3'], [',', ',', '|'])

    Name    test1   test2   Count   test3
0   Emp1    X       A       1       X1
1   Emp1    X       A       1       X2
2   Emp1    X       A       1       X3
3   Emp1    Y       A       1       X1
4   Emp1    Y       A       1       X2
5   Emp1    Y       A       1       X3
6   Emp2    X       A       2       X4
7   Emp2    X       B       2       X4
8   Emp2    X       C       2       X4
9   Emp3    Z       C       3       X5
>>> expand(df, 'test1')

    Name    test1   test2   Count
0   Emp1    X       A       1
1   Emp1    Y       A       1
2   Emp2    X       A,B,C   2
3   Emp3    Z       C       3

>>> expand(df, 'test2')

    Name    test1   test2   Count
0   Emp1    X,Y     A       1
1   Emp2    X       A       2
2   Emp2    X       B       2
3   Emp2    X       C       2
4   Emp3    Z       C       3

>>> expand(expand(df, 'test2'), 'test1') 

    Name    test1   test2   Count
0   Emp1    X       A       1
1   Emp1    Y       A       1
2   Emp2    X       A       2
3   Emp2    X       B       2
4   Emp2    X       C       2
5   Emp3    Z       C       3


>>> expand(expand(df, 'test2'), 'test1').eq(expand(expand(df, 'test1'), 'test2')).all()

Name     True
test1    True
test2    True
Count    True
dtype: bool
pd.DataFrame(
    [(n, a, b, c)
     for n, A, B, c in zip(*map(df.get, df))
     for a in A.split(',') for b in B.split(',')],
    columns=df.columns
)

   Name test1 test2  Count
0  Emp1     X     A      1
1  Emp1     Y     A      1
2  Emp2     X     A      2
3  Emp2     X     B      2
4  Emp2     X     C      2
5  Emp3     Z     C      3