Combine two columns of text in dataframe in pandas/python

匿名 (未验证) 提交于 2019-12-03 02:11:02

问题:

I have a 20 x 4000 dataframe in python using pandas. Two of these columns are named Year and quarter. I'd like to create a variable called period that makes Year = 2000 and quarter= q2 into 2000q2

Can anyone help with that?

回答1:

dataframe["period"] = dataframe["Year"].map(str) + dataframe["quarter"] 


回答2:

df = pd.DataFrame({'Year': ['2014', '2015'], 'quarter': ['q1', 'q2']}) df['period'] = df[['Year', 'quarter']].apply(lambda x: ''.join(x), axis=1) 

Yields this dataframe

   Year quarter  period 0  2014      q1  2014q1 1  2015      q2  2015q2 

This method generalizes to an arbitrary number of string columns by replacing df[['Year', 'quarter']] with any column slice of your dataframe, e.g. df.iloc[:,0:2].apply(lambda x: ''.join(x), axis=1).

You can check more information about apply() method here



回答3:

yet another ways to do this:

df['period'] = df['Year'].astype(str) + df['quarter'] 

or bit slower:

df['period'] = df[['Year','quarter']].astype(str).sum(axis=1) 

Let's test it on 200K rows 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) 

UPDATE: new timings using Pandas 0.19.0

Timing without CPU/GPU optimization (sorted from fastest to slowest):

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 

Timing using CPU/GPU optimization:

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 


回答4:

The method cat() of the .str accessor works really well for this:

>>> import pandas as pd >>> df = pd.DataFrame([["2014", "q1"],  ...                    ["2015", "q3"]], ...                   columns=('Year', 'Quarter')) >>> print(df)    Year Quarter 0  2014      q1 1  2015      q3 >>> df['Period'] = df.Year.str.cat(df.Quarter) >>> print(df)    Year Quarter  Period 0  2014      q1  2014q1 1  2015      q3  2015q3 

cat() even allows you to add a separator so, for example, suppose you only have integers for year and period, you can do this:

>>> import pandas as pd >>> df = pd.DataFrame([[2014, 1], ...                    [2015, 3]], ...                   columns=('Year', 'Quarter')) >>> print(df)    Year Quarter 0  2014       1 1  2015       3 >>> df['Period'] = df.Year.astype(str).str.cat(df.Quarter.astype(str), sep='q') >>> print(df)    Year Quarter  Period 0  2014       1  2014q1 1  2015       3  2015q3 


回答5:

Use of a lamba function this time with string.format().

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 

This allows you to work with non-strings and reformat values as needed.

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 


回答6:

As your data are inserted to a dataframe, this command should solve your problem:

df['period'] = df[['Year', 'quarter']].apply(lambda x: ' '.join(x.astype(str)), axis=1) 


回答7:

Although the @silvado answer is good if you change df.map(str) to df.astype(str) it will be faster:

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 


回答8:

Here is an implementation that I find very versatile:

In [1]: import pandas as pd   In [2]: df = pd.DataFrame([[0, 'the', 'quick', 'brown'],    ...:                    [1, 'fox', 'jumps', 'over'],     ...:                    [2, 'the', 'lazy', 'dog']],    ...:                   columns=['c0', 'c1', 'c2', 'c3'])  In [3]: def str_join(df, sep, *cols):    ...:     from functools import reduce    ...:     return reduce(lambda x, y: x.astype(str).str.cat(y.astype(str), sep=sep),     ...:                   [df[col] for col in cols])    ...:   In [4]: df['cat'] = str_join(df, '-', 'c0', 'c1', 'c2', 'c3')  In [5]: df Out[5]:     c0   c1     c2     c3                cat 0   0  the  quick  brown  0-the-quick-brown 1   1  fox  jumps   over   1-fox-jumps-over 2   2  the   lazy    dog     2-the-lazy-dog 


回答9:

more efficient is

def concat_df_str1(df):     """ run time: 1.3416s """     return pd.Series([''.join(row.astype(str)) for row in df.values], index=df.index) 

and here is a time test:

import numpy as np import pandas as pd  from time import time   def concat_df_str1(df):     """ run time: 1.3416s """     return pd.Series([''.join(row.astype(str)) for row in df.values], index=df.index)   def concat_df_str2(df):     """ run time: 5.2758s """     return df.astype(str).sum(axis=1)   def concat_df_str3(df):     """ run time: 5.0076s """     df = df.astype(str)     return df[0] + df[1] + df[2] + df[3] + df[4] + \            df[5] + df[6] + df[7] + df[8] + df[9]   def concat_df_str4(df):     """ run time: 7.8624s """     return df.astype(str).apply(lambda x: ''.join(x), axis=1)   def main():     df = pd.DataFrame(np.zeros(1000000).reshape(100000, 10))     df = df.astype(int)      time1 = time()     df_en = concat_df_str4(df)     print('run time: %.4fs' % (time() - time1))     print(df_en.head(10))   if __name__ == '__main__':     main() 

final, when sum(concat_df_str2) is used, the result is not simply concat, it will trans to integer.



回答10:

As many have mentioned previously, you must convert each column to string and then use the plus operator to combine two string columns. You can get a large performance improvement by using NumPy.

%timeit df['Year'].values.astype(str) + df.quarter 71.1 ms ± 3.76 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)  %timeit df['Year'].astype(str) + df['quarter'] 565 ms ± 22.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 


回答11:

Use .combine_first.

df['Period'] = df['Year'].combine_first(df['Quarter']) 


回答12:

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) 

For example:

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 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!