我有一个20 x 4000的数据帧在Python中使用熊猫。其中两列分别命名为Year和quarter。我想创建一个名为period的变量,使Year = 2000, quarter= q2变为2000q2。
有人能帮忙吗?
我有一个20 x 4000的数据帧在Python中使用熊猫。其中两列分别命名为Year和quarter。我想创建一个名为period的变量,使Year = 2000, quarter= q2变为2000q2。
有人能帮忙吗?
当前回答
如果两个列都是字符串,你可以直接连接它们:
df["period"] = df["Year"] + df["quarter"]
如果一个(或两个)列不是字符串类型的,你应该先转换它(它们),
df["period"] = df["Year"].astype(str) + df["quarter"]
这样做时要当心nan !
如果你需要连接多个字符串列,你可以使用agg:
df['period'] = df[['Year', 'quarter', ...]].agg('-'.join, axis=1)
其中“-”是分隔符。
其他回答
让我们假设你的数据框架是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']
小数据集(< 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"])
这次使用了string.format()的lamba函数。
import pandas as pd
df = pd.DataFrame({'Year': ['2014', '2015'], 'Quarter': ['q1', 'q2']})
print df
df['YearQuarter'] = df[['Year','Quarter']].apply(lambda x : '{}{}'.format(x[0],x[1]), axis=1)
print df
Quarter Year
0 q1 2014
1 q2 2015
Quarter Year YearQuarter
0 q1 2014 2014q1
1 q2 2015 2015q2
这允许您使用非字符串并根据需要重新格式化值。
import pandas as pd
df = pd.DataFrame({'Year': ['2014', '2015'], 'Quarter': [1, 2]})
print df.dtypes
print df
df['YearQuarter'] = df[['Year','Quarter']].apply(lambda x : '{}q{}'.format(x[0],x[1]), axis=1)
print df
Quarter int64
Year object
dtype: object
Quarter Year
0 1 2014
1 2 2015
Quarter Year YearQuarter
0 1 2014 2014q1
1 2 2015 2015q2
你可以使用lambda:
combine_lambda = lambda x: '{}{}'.format(x.Year, x.quarter)
然后使用它来创建新列:
df['period'] = df.apply(combine_lambda, axis = 1)