Hi my dataframe look like:
Store,Dept,Date,Sales
1,1,2010年02月05日,245
1,1,2010年02月12日,449
1,1,2010年02月19日,455
1,1,2010年02月26日,154
1,1,2010年03月05日,29
1,1,2010年03月12日,239
1,1,2010年03月19日,264
Simply, I need to add another column called '_id' as concatenation of Store, Dept, Date like "1_1_2010年02月05日", I assume I can do it through df['id'] = df['Store'] +'' +df['Dept'] +'_'+df['Date'], but it turned out to be not.
Similarly, i also need to add a new column as log of sales, I tried df['logSales'] = math.log(df['Sales']), again, it did not work.
2 Answers 2
You can first convert it to strings (the integer columns) before concatenating with +:
In [25]: df['id'] = df['Store'].astype(str) +'_' +df['Dept'].astype(str) +'_'+df['Date']
In [26]: df
Out[26]:
Store Dept Date Sales id
0 1 1 2010年02月05日 245 1_1_2010年02月05日
1 1 1 2010年02月12日 449 1_1_2010年02月12日
2 1 1 2010年02月19日 455 1_1_2010年02月19日
3 1 1 2010年02月26日 154 1_1_2010年02月26日
4 1 1 2010年03月05日 29 1_1_2010年03月05日
5 1 1 2010年03月12日 239 1_1_2010年03月12日
6 1 1 2010年03月19日 264 1_1_2010年03月19日
For the log, you better use the numpy function. This is vectorized (math.log can only work on single scalar values):
In [34]: df['logSales'] = np.log(df['Sales'])
In [35]: df
Out[35]:
Store Dept Date Sales id logSales
0 1 1 2010年02月05日 245 1_1_2010年02月05日 5.501258
1 1 1 2010年02月12日 449 1_1_2010年02月12日 6.107023
2 1 1 2010年02月19日 455 1_1_2010年02月19日 6.120297
3 1 1 2010年02月26日 154 1_1_2010年02月26日 5.036953
4 1 1 2010年03月05日 29 1_1_2010年03月05日 3.367296
5 1 1 2010年03月12日 239 1_1_2010年03月12日 5.476464
6 1 1 2010年03月19日 264 1_1_2010年03月19日 5.575949
Summarizing the comments, for a dataframe of this size, using apply will not differ much in performance compared to using vectorized functions (working on the full column), but when your real dataframe becomes larger, it will.
Apart from that, I think the above solution is also easier syntax.
12 Comments
In [153]:
import pandas as pd
import io
temp = """Store,Dept,Date,Sales
1,1,2010年02月05日,245
1,1,2010年02月12日,449
1,1,2010年02月19日,455
1,1,2010年02月26日,154
1,1,2010年03月05日,29
1,1,2010年03月12日,239
1,1,2010年03月19日,264"""
df = pd.read_csv(io.StringIO(temp))
df
Out[153]:
Store Dept Date Sales
0 1 1 2010年02月05日 245
1 1 1 2010年02月12日 449
2 1 1 2010年02月19日 455
3 1 1 2010年02月26日 154
4 1 1 2010年03月05日 29
5 1 1 2010年03月12日 239
6 1 1 2010年03月19日 264
[7 rows x 4 columns]
In [154]:
# apply a lambda function row-wise, you need to convert store and dept to strings in order to build the new string
df['id'] = df.apply(lambda x: str(str(x['Store']) + ' ' + str(x['Dept']) +'_'+x['Date']), axis=1)
df
Out[154]:
Store Dept Date Sales id
0 1 1 2010年02月05日 245 1 1_2010年02月05日
1 1 1 2010年02月12日 449 1 1_2010年02月12日
2 1 1 2010年02月19日 455 1 1_2010年02月19日
3 1 1 2010年02月26日 154 1 1_2010年02月26日
4 1 1 2010年03月05日 29 1 1_2010年03月05日
5 1 1 2010年03月12日 239 1 1_2010年03月12日
6 1 1 2010年03月19日 264 1 1_2010年03月19日
[7 rows x 5 columns]
In [155]:
import math
# now apply log to sales to create the new column
df['logSales'] = df['Sales'].apply(math.log)
df
Out[155]:
Store Dept Date Sales id logSales
0 1 1 2010年02月05日 245 1 1_2010年02月05日 5.501258
1 1 1 2010年02月12日 449 1 1_2010年02月12日 6.107023
2 1 1 2010年02月19日 455 1 1_2010年02月19日 6.120297
3 1 1 2010年02月26日 154 1 1_2010年02月26日 5.036953
4 1 1 2010年03月05日 29 1 1_2010年03月05日 3.367296
5 1 1 2010年03月12日 239 1 1_2010年03月12日 5.476464
6 1 1 2010年03月19日 264 1 1_2010年03月19日 5.575949
[7 rows x 6 columns]