创建新列并使用下划线填充添加的字符串来自相同的df作为分隔符

时间:2017-08-18 12:37:06

标签: python pandas dataframe

我有以下DataFrame:

import pandas as pd
ds = pd.DataFrame({'place': [1,2,3], 'date': ['6/7/2021','1/1/2031','1/4/2011'], 
'city':['Moscow','New York','Sidney'], 'kids':[5,3,1]})

看起来像这样:

city        date      kids   place
Moscow    6/7/2021     5       1
New York  1/1/2031     3       2
Sidney    1/4/2011     1       3

我需要向DataFrame添加一个新列'key',其中的值将是一个字符串,它将是某些列的每一行中的值的并集:'city','date','place'with作为分隔符的下划线('_')。

最终目标:

city        date      kids   place   key
Moscow    6/7/2021     5       1     Moscow_6/7/2021_1
New York  1/1/2031     3       2     New York_1/1/2031_2
Sidney    1/4/2011     1       3     Sidney_1/4/2011_3

首先,我将'place'列中的整数转换为字符串:

df['place'].apply(str)

其次,我删除了我不需要的列(但实际上这个列应该在生成的df中):

col_list= list(df)
col_list.remove('kids')

然后我尝试创建一个新列并用附加的字符串填充它:

df['key'] = df[col_list].apply(lambda x: x.sum())

但是它返回了'key'列中的NaN值,实际值仍然附加了不是作为分隔符的undersoce。

4 个答案:

答案 0 :(得分:5)

您只需添加类似于构建str的列,您只需将最后一列投射到str

In[87]:
df['key'] = df['city'] + '_' + df['date'] + '_' + df['place'].astype(str)
df

Out[87]: 
       city      date  kids  place                  key
0    Moscow  6/7/2021     5      1    Moscow_6/7/2021_1
1  New York  1/1/2031     3      2  New York_1/1/2031_2
2    Sidney  1/4/2011     1      3    Sidney_1/4/2011_3

<强>计时 有一个30k行df:

%timeit  df['city'] + '_' + df['date'] + '_' + df['place'].astype(str)
df
%timeit df[['city', 'date', 'place']].astype(str).apply('_'.join, 1)
%timeit df[['city', 'date', 'place']].astype(str).transform('_'.join, 1)

100 loops, best of 3: 9 ms per loop
10 loops, best of 3: 84 ms per loop
10 loops, best of 3: 83 ms per loop

这个方法似乎要快10倍,可能因为它只是一个直接的矢量化加法,apply是一个cythonised for循环,它看起来像transform需要做的某种形式的grouping,排序,然后创建一个索引与原始df对齐的新对象,这是我猜的时间

其他@JohnGalt方法:

%timeit pd.Series(df[['city', 'date', 'place']].astype(str).values.tolist()).str.join('_')

100 loops, best of 3: 10.5 ms per loop

所以这比我的回答慢一点。

答案 1 :(得分:4)

您可以使用apply更加通用并加入

In [485]: ds[['city', 'date', 'place']].astype(str).apply('_'.join, 1)
Out[485]:
0      Moscow_6/7/2021_1
1    New York_1/1/2031_2
2      Sidney_1/4/2011_3
dtype: object

In [486]: ds['key'] = ds[['city', 'date', 'place']].astype(str).apply('_'.join, 1)

In [487]: ds
Out[487]:
       city      date  kids  place                  key
0    Moscow  6/7/2021     5      1    Moscow_6/7/2021_1
1  New York  1/1/2031     3      2  New York_1/1/2031_2
2    Sidney  1/4/2011     1      3    Sidney_1/4/2011_3

或者,要使用.str方法,您可以

In [493]: pd.Series(ds[['city', 'date', 'place']].astype(str).values.tolist()).str.join('_')
Out[493]:
0      Moscow_6/7/2021_1
1    New York_1/1/2031_2
2      Sidney_1/4/2011_3
dtype: object

答案 2 :(得分:2)

使用def fit(self, x, y): ... for xi, target in zip(x, y): update = self.eta * (target - self.predict(xi.reshape(1, x.shape[1])) ... # Here if you want to implement perceptron, use matmul not dot product def net_input(self, x): return np.matmul(x, self.w_[1:]) + self.w_[0] (v0.20 +):

尝试df.assign
df.transform

请注意In [203]: df.assign(key=df[['city', 'date', 'place']].astype(str).transform('_'.join, 1)) Out[203]: city date kids place key 0 Moscow 6/7/2021 5 1 Moscow_6/7/2021_1 1 New York 1/1/2031 3 2 New York_1/1/2031_2 2 Sidney 1/4/2011 1 3 Sidney_1/4/2011_3 不在位,要保留更改,您需要:df.assign

答案 3 :(得分:0)

申请也可以完成这项工作:

df[key] = df[columns].apply(lambda x: '_'.join([str(y) for y in x]))