连接pandas数据框中的所有列

2024-05-20 16:24:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我有多个pandas数据框,其中可能有不同数量的列,这些列的数量通常从50到100不等。我需要创建一个最后的列,它只是连接所有列。基本上,列的第一行中的字符串应该是所有列的第一行中字符串的总和(连接)。我在下面写了一个循环,但我觉得可能有更好的更有效的方法来做这件事。有什么办法吗

num_columns = df.columns.shape[0]
col_names = df.columns.values.tolist()
df.loc[:, 'merged'] = ""
for each_col_ind in range(num_columns):
    print('Concatenating', col_names[each_col_ind])
    df.loc[:, 'merged'] = df.loc[:, 'merged'] + df[col_names[each_col_ind]]

Tags: columns数据方法字符串pandasdf数量names
3条回答

我没有足够的声誉发表评论,所以我正在建立我的答案从黑网站的反应。

为了清楚起见,LunchBox评论说,Python3.7.0失败了。在Python 3.6.3上也失败了。以下是blacksite的原始答案:

df['concat'] = pd.Series(df.fillna('').values.tolist()).str.join('')

以下是我对Python3.6.3的修改:

df['concat'] = pd.Series(df.fillna('').values.tolist()).map(lambda x: ''.join(map(str,x)))

^{}溶解,但输出是float,因此转换成intstr是必要的:

df['new'] = df.sum(axis=1).astype(int).astype(str)

另一个具有apply函数join的解决方案,但它最慢:

df['new'] = df.apply(''.join, axis=1)

最后一个非常快的numpy solution-转换成numpy array,然后'sum'

df['new'] = df.values.sum(axis=1)

计时

df = pd.DataFrame({'A': ['1', '2', '3'], 'B': ['4', '5', '6'], 'C': ['7', '8', '9']})
#[30000 rows x 3 columns]
df = pd.concat([df]*10000).reset_index(drop=True)
#print (df)

cols = list('ABC')

#not_a_robot solution
In [259]: %timeit df['concat'] = pd.Series(df[cols].fillna('').values.tolist()).str.join('')
100 loops, best of 3: 17.4 ms per loop

In [260]: %timeit df['new'] = df[cols].astype(str).apply(''.join, axis=1)
1 loop, best of 3: 386 ms per loop

In [261]: %timeit df['new1'] = df[cols].values.sum(axis=1)
100 loops, best of 3: 6.5 ms per loop

In [262]: %timeit df['new2'] = df[cols].astype(str).sum(axis=1).astype(int).astype(str)
10 loops, best of 3: 68.6 ms per loop

如果某些列的数据类型不是由^{}强制转换的object(显然是string),请编辑:

df['new'] = df.astype(str).values.sum(axis=1)
df = pd.DataFrame({'A': ['1', '2', '3'], 'B': ['4', '5', '6'], 'C': ['7', '8', '9']})

df['concat'] = pd.Series(df.fillna('').values.tolist()).str.join('')

给我们:

df
Out[6]: 
   A  B  C concat
0  1  4  7    147
1  2  5  8    258
2  3  6  9    369

要选择给定的列集,请执行以下操作:

df['concat'] = pd.Series(df[['A', 'B']].fillna('').values.tolist()).str.join('')

df
Out[8]: 
   A  B  C concat
0  1  4  7     14
1  2  5  8     25
2  3  6  9     36

但是,我注意到,这种方法有时会导致NaN被填充到不应该填充的地方,所以这里有另一种方法:

>>> from functools import reduce
>>> df['concat'] = df[cols].apply(lambda x: reduce(lambda a, b: a + b, x), axis=1)
>>> df
   A  B  C concat
0  1  4  7    147
1  2  5  8    258
2  3  6  9    369

尽管应该指出,这种方法要慢得多:

$ python3 -m timeit 'import pandas as pd;from functools import reduce; df=pd.DataFrame({"a": ["this", "is", "a", "string"] * 5000, "b": ["this", "is", "a", "string"] * 5000});[df[["a", "b"]].apply(lambda x: reduce(lambda a, b: a + b, x)) for _ in range(10)]'
10 loops, best of 3: 451 msec per loop

$ python3 -m timeit 'import pandas as pd;from functools import reduce; df=pd.DataFrame({"a": ["this", "is", "a", "string"] * 5000, "b": ["this", "is", "a", "string"] * 5000});[pd.Series(df[["a", "b"]].fillna("").values.tolist()).str.join(" ") for _ in range(10)]'
10 loops, best of 3: 98.5 msec per loop

相关问题 更多 >