Python Pandas 合并数据框中的同名列

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24390645/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 22:11:51  来源:igfitidea点击:

Python Pandas merge samed name columns in a dataframe

pythonpandas

提问by Wizuriel

So I have a few CSV files I'm trying to work with, but some of them have multiple columns with the same name.

所以我有几个 CSV 文件我正在尝试使用,但其中一些有多个同名的列。

For example I could have a csv like this:

例如,我可以有一个这样的 csv:

ID   Name   a    a    a     b    b
1    test1  1    NaN  NaN   "a"  NaN
2    test2  NaN  2    NaN   "a"  NaN
3    test3  2    3    NaN   NaN  "b"
4    test4  NaN  NaN  4     NaN  "b"

loading into pandasis giving me this:

加载到 pandasis 给我这个:

ID   Name   a    a.1  a.2   b    b.1
1    test1  1    NaN  NaN   "a"  NaN
2    test2  NaN  2    NaN   "a"  NaN
3    test3  2    3    NaN   NaN  "b"
4    test4  NaN  NaN  4     NaN  "b"

What I would like to do is merge those same name columns into 1 column (if there are multiple values keeping those values separate) and my ideal output would be this

我想要做的是将这些相同名称的列合并为 1 列(如果有多个值将这些值分开),我的理想输出是这样的

ID   Name   a      b  
1    test1  "1"    "a"   
2    test2  "2"    "a"
3    test3  "2;3"  "b"
4    test4  "4"    "b"

So wondering if this is possible?

所以想知道这是否可能?

回答by DSM

You could use groupbyon axis=1, and experiment with something like

你可以使用groupbyon axis=1,并尝试类似的东西

>>> def sjoin(x): return ';'.join(x[x.notnull()].astype(str))
>>> df.groupby(level=0, axis=1).apply(lambda x: x.apply(sjoin, axis=1))
  ID   Name        a  b
0  1  test1      1.0  a
1  2  test2      2.0  a
2  3  test3  2.0;3.0  b
3  4  test4      4.0  b

where instead of using .astype(str), you could use whatever formatting operator you wanted.

.astype(str)您可以使用您想要的任何格式运算符而不是使用。

回答by CT Zhu

Probably it is not a good idea to have duplicated column names, but it will work:

列名重复可能不是一个好主意,但它会起作用:

In [72]:

df2=df[['ID', 'Name']]
df2['a']='"'+df.T[df.columns.values=='a'].apply(lambda x: ';'.join(["%i"%item for item in x[x.notnull()]]))+'"' #these columns are of float dtype
df2['b']=df.T[df.columns.values=='b'].apply(lambda x: ';'.join([item for item in x[x.notnull()]])) #these columns are of objects dtype
print df2
   ID   Name      a    b
0   1  test1    "1"  "a"
1   2  test2    "2"  "a"
2   3  test3  "2;3"  "b"
3   4  test4    "4"  "b"

[4 rows x 4 columns]

回答by Paul H

Of course DSM and CT Zhu have marvelously concise answers that utilize a lot built in features of Python in general and dataframe in particular. Here's something a little -- [cough] -- verbose.

当然,DSM 和 CT Zhu 有非常简洁的答案,它们利用了 Python 的许多内置特性,特别是数据帧。这里有点——[咳嗽]——冗长。

def myJoiner(row):
    newrow = []
    for r in row:
        if not pandas.isnull(r):
            newrow.append(str(r))
    return ';'.join(newrow)

def groupCols(df, key):
    columns = df.select(lambda col: key in col, axis=1)
    joined = columns.apply(myJoiner, axis=1)
    joined.name = key
    return pandas.DataFrame(joined)

import pandas 
from io import StringIO  # python 3.X
#from StringIO import StringIO #python 2.X

data = StringIO("""\
ID   Name   a    a    a     b    b
1    test1  1    NaN  NaN   "a"  NaN
2    test2  NaN  2    NaN   "a"  NaN
3    test3  2    3    NaN   NaN  "b"
4    test4  NaN  NaN  4     NaN  "b"
""")

df = pandas.read_table(data, sep='\s+')
df.set_index(['ID', 'Name'], inplace=True)


AB = groupCols(df, 'a').join(groupCols(df, 'b'))
print(AB)

Which gives me:

这给了我:

                a  b
ID Name             
1  test1      1.0  a
2  test2      2.0  a
3  test3  2.0;3.0  b
4  test4      4.0  b