我有一个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)