def madd(x):
"""Performs element-wise string concatenation with multiple input arrays.
Args:
x: iterable of np.array.
Returns: np.array.
"""
for i, arr in enumerate(x):
if type(arr.item(0)) is not str:
x[i] = x[i].astype(str)
return reduce(np.core.defchararray.add, x)
例如:
data = list(zip([2000]*4, ['q1', 'q2', 'q3', 'q4']))
df = pd.DataFrame(data=data, columns=['Year', 'quarter'])
df['period'] = madd([df[col].values for col in ['Year', 'quarter']])
df
Year quarter period
0 2000 q1 2000q1
1 2000 q2 2000q2
2 2000 q3 2000q3
3 2000 q4 2000q4
# be cautious about the separator, some symbols may cause "SyntaxError: EOL while scanning string literal".
# e.g. ";;" as separator would raise the SyntaxError
separator = "&&"
# pd.Series.str.cat() method does not work to concatenate / combine two columns with int value and str value. This would raise "AttributeError: Can only use .cat accessor with a 'category' dtype"
df["period"] = df["Year"].map(str) + separator + df["quarter"]
df["period"] = df[['Year','quarter']].apply(lambda x : '{} && {}'.format(x[0],x[1]), axis=1)
df["period"] = df.apply(lambda x: f'{x["Year"]} && {x["quarter"]}', axis=1)
[''.join(i) for i in zip(df["Year"].map(str),df["quarter"])]
或稍慢但更紧凑:
df.Year.str.cat(df.quarter)
较大的数据集(>150行)
df['Year'].astype(str) + df['quarter']
更新:时序图0.23.4
让我们在200k行df上测试它:
In [250]: df
Out[250]:
Year quarter
0 2014 q1
1 2015 q2
In [251]: df = pd.concat([df] * 10**5)
In [252]: df.shape
Out[252]: (200000, 2)
更新:使用pandas 0.19.0的新计时 没有cpu/gpu优化的计时(从最快到最慢排序):
In [107]: %timeit df['Year'].astype(str) + df['quarter']
10 loops, best of 3: 131 ms per loop
In [106]: %timeit df['Year'].map(str) + df['quarter']
10 loops, best of 3: 161 ms per loop
In [108]: %timeit df.Year.str.cat(df.quarter)
10 loops, best of 3: 189 ms per loop
In [109]: %timeit df.loc[:, ['Year','quarter']].astype(str).sum(axis=1)
1 loop, best of 3: 567 ms per loop
In [110]: %timeit df[['Year','quarter']].astype(str).sum(axis=1)
1 loop, best of 3: 584 ms per loop
In [111]: %timeit df[['Year','quarter']].apply(lambda x : '{}{}'.format(x[0],x[1]), axis=1)
1 loop, best of 3: 24.7 s per loop
使用cpu/gpu优化的计时:
In [113]: %timeit df['Year'].astype(str) + df['quarter']
10 loops, best of 3: 53.3 ms per loop
In [114]: %timeit df['Year'].map(str) + df['quarter']
10 loops, best of 3: 65.5 ms per loop
In [115]: %timeit df.Year.str.cat(df.quarter)
10 loops, best of 3: 79.9 ms per loop
In [116]: %timeit df.loc[:, ['Year','quarter']].astype(str).sum(axis=1)
1 loop, best of 3: 230 ms per loop
In [117]: %timeit df[['Year','quarter']].astype(str).sum(axis=1)
1 loop, best of 3: 230 ms per loop
In [118]: %timeit df[['Year','quarter']].apply(lambda x : '{}{}'.format(x[0],x[1]), axis=1)
1 loop, best of 3: 9.38 s per loop
import pandas as pd
df = pd.DataFrame({'Year': ['2014', '2015'], 'quarter': ['q1', 'q2']})
In [131]: %timeit df["Year"].map(str)
10000 loops, best of 3: 132 us per loop
In [132]: %timeit df["Year"].astype(str)
10000 loops, best of 3: 82.2 us per loop
19条答案
按热度按时间ss2ws0br1#
可以使用dataframe的分配方法:
ikfrs5lh2#
例如:
hmmo2u0o3#
使用
.combine_first
.wydwbb8l4#
下面是我对上述解决方案的总结,使用列值之间的分隔符,将两个具有int和str值的列连接/组合到一个新列中。为此,有三种解决方案。
ruoxqz4g5#
我的看法。。。。
zaq34kh66#
正如前面提到的,您必须将每个列转换为字符串,然后使用加号运算符组合两个字符串列。通过使用numpy,您可以获得很大的性能改进。
a5g8bdjr7#
如果两列都是字符串,则可以直接连接它们:
如果其中一列(或两列)不是字符串类型,则应首先转换该列,
做这件事时要当心南斯!
如果需要连接多个字符串列,可以使用
agg
:其中“-”是分隔符。
mbzjlibv8#
小型数据集(<150行)
或稍慢但更紧凑:
较大的数据集(>150行)
更新:时序图0.23.4
让我们在200k行df上测试它:
更新:使用pandas 0.19.0的新计时
没有cpu/gpu优化的计时(从最快到最慢排序):
使用cpu/gpu优化的计时:
回答@anton vbr的贡献
kmpatx3s9#
生成此 Dataframe
此方法通过替换
df[['Year', 'quarter']]
使用 Dataframe 的任何列切片,例如。df.iloc[:,0:2].apply(lambda x: ''.join(x), axis=1)
.您可以在此处查看有关apply()方法的更多信息
vof42yt110#
方法
cat()
的.str
accessor在这方面非常有效:6tr1vspr11#
这次将lamba函数与string.format()一起使用。
这允许您使用非字符串并根据需要重新格式化值。
2hh7jdfx12#
概括到多个列,为什么不:
qacovj5a13#
尽管@silvado的答案是好的,如果你改变
df.map(str)
到df.astype(str)
它将更快:weylhg0b14#
让我们假设你的
dataframe
是df
带柱Year
及Quarter
.假设我们想要看到 Dataframe ;
最后,连接
Year
和Quarter
具体如下。你现在可以
print
df
查看生成的 Dataframe 。如果你不想要年和季度之间的空间,只需通过这样做来移除它;
yi0zb3m415#
以下是一个我认为非常通用的实现: