我有一个20 x 4000的数据帧在Python中使用熊猫。其中两列分别命名为Year和quarter。我想创建一个名为period的变量,使Year = 2000, quarter= q2变为2000q2。
有人能帮忙吗?
我有一个20 x 4000的数据帧在Python中使用熊猫。其中两列分别命名为Year和quarter。我想创建一个名为period的变量,使Year = 2000, quarter= q2变为2000q2。
有人能帮忙吗?
当前回答
小数据集(< 150行)
[''.join(i) for i in zip(df["Year"].map(str),df["quarter"])]
或者稍慢但更紧凑:
df.Year.str.cat(df.quarter)
更大的数据集(> 150rows)
df['Year'].astype(str) + df['quarter']
更新:定时图熊猫0.23.4
让我们在200K行上测试一下:
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)
更新:新的计时使用熊猫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
回答@anton-vbr的贡献
其他回答
当使用加法运算符+将列与字符串连接起来时,如果其中任何一个是NaN,则整个输出将是NaN,因此使用fillna()
df["join"] = "some" + df["col"].fillna(df["val_if_nan"])
df = pd.DataFrame({'Year': ['2014', '2015'], 'quarter': ['q1', 'q2']})
df['period'] = df[['Year', 'quarter']].apply(lambda x: ''.join(x), axis=1)
产生这个数据框架
Year quarter period
0 2014 q1 2014q1
1 2015 q2 2015q2
该方法通过将df[['Year', 'quarter']]替换为数据帧的任意列片来泛化任意数量的字符串列,例如df.iloc[:,0:2]。Apply (lambda x: " .join(x), axis=1)。
您可以在这里查看有关apply()方法的更多信息
让我们假设你的数据框架是df,列是Year和Quarter。
import pandas as pd
df = pd.DataFrame({'Quarter':'q1 q2 q3 q4'.split(), 'Year':'2000'})
假设我们想要查看数据框架;
df
>>> Quarter Year
0 q1 2000
1 q2 2000
2 q3 2000
3 q4 2000
最后,将年度和季度连接起来,如下所示。
df['Period'] = df['Year'] + ' ' + df['Quarter']
现在可以打印df来查看结果的数据框架。
df
>>> Quarter Year Period
0 q1 2000 2000 q1
1 q2 2000 2000 q2
2 q3 2000 2000 q3
3 q4 2000 2000 q4
如果你不想要年和季度之间的空间,只需删除它做;
df['Period'] = df['Year'] + df['Quarter']
使用.combine_first。
df['Period'] = df['Year'].combine_first(df['Quarter'])
类似于@geher的答案,但可以使用任何你喜欢的分隔符:
SEP = " "
INPUT_COLUMNS_WITH_SEP = ",sep,".join(INPUT_COLUMNS).split(",")
df.assign(sep=SEP)[INPUT_COLUMNS_WITH_SEP].sum(axis=1)