在pandas数据框中原地更改列的值

7
我有一个pandas数据框。
keyword                     adGroup     goal6Value   adCost
aaaa                        (not set)   0            0.0
+bbbb                       (not set)   0            0.0
+cccc                       (not set)   2072         0.0
dddd                        (not set)   0            0.0

我更改了第一列中的值,根据某些条件(如果没有“+”符号,则添加括号)在关键词上添加括号。

keyword                     adGroup     goal6Value   adCost
[aaaa]                      (not set)   0            0.0
+bbbb                       (not set)   0            0.0
+cccc                       (not set)   2072         0.0
[dddd]                      (not set)   0            0.0

这是创建添加括号的函数:
def add_bracket(df):

    df["keyword"] = df["keyword"].astype('str')
    keyword_list = list()

    for index, row in df.iterrows():
       keyword = row["keyword"]
       if keyword.find("+") < 0:
         keyword = "[" + keyword + "]"
       keyword_list.append(keyword)

    kw = pd.DataFrame(keyword_list, columns = ['Keyword2'])
    df2 = pd.concat([df, kw], axis=1).drop(columns["keyword"]).rename(columns={'Keyword2': 'keyword'})
    df2 = df2[['keyword', 'adGroup', 'goal6Value', 'adCost']]
    return df2

这个函数产生了我想要的结果,但是在pandas中有没有更简洁的方法,以便我不需要创建df2来添加第一列的输出(基本上是就地进行更改)?

解决方案: 根据@Inder提出的建议,整个函数可以用一行代码写成。

df["keyword"] = df.keyword.apply(lambda x: "[" + x + "]" if x.find("+") < 0 else x)

基于 @RafaelC 的回答。

mask = df.keyword.str.contains('+', regex=False)
df.loc[~mask, 'keyword'] = "[" + df.loc[~mask, 'keyword'] + "]"

1
@coldspeed 匹配关键词与另一个文档。 - azmirfakkri
2个回答

7

仅求和

mask = df.keyword.str.contains('+', regex=False)
df.loc[~mask, 'keyword'] = "[" + df.loc[~mask, 'keyword'] + "]"

    keyword 
0   [aaaa]  
1   [bbbb]  
2   [cccc]  
3   [dddd]  

为什么这比apply更好?

看一下时间:

%timeit "[" + df.loc[mask, 'keyword'] + "]"
348 µs ± 24.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit df.keyword.apply(lambda x:[x])
112 µs ± 3.46 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

哇,apply函数更快吗?

不完全是这样。在非常小的df上可能会更快,但看一下在一个比较大的df上进行相同操作(有100,000倍的行数):

df = pd.concat([df]*100000)

%timeit "[" + df.loc[mask, 'keyword'] + "]"
4.54 ms ± 135 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit df.keyword.apply(lambda x:[x])
129 ms ± 2.74 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

所以apply会变得非常非常慢,但矢量化操作不会。

@mahf_i,有比使用“apply”更好的方法。我会编辑我的答案。 - rafaelc
你能解释一下为什么这种方法比“apply”更好吗? - azmirfakkri
1
@mahf_i 因为 apply 很慢,我已经添加了一些时间记录 :) - rafaelc
这两者不同。Lambda函数返回一个包含x的列表,即[x],而不是带有大括号的字符串:'['+str(x)+']'。 - Danyal

2
您可以使用 apply 来实现此目的:
df["keyword"]=df.keyword.apply(lambda x:[x])

如果使用dataframe.name_of_column.apply("operation"),输出结果将会是:

keyword                     adGroup     goal6Value   adCost
[aaaa]                      (not set)   0            0.0
[bbbb]                      (not set)   0            0.0
[cccc]                      (not set)   2072         0.0
[dddd]                      (not set)   0            0.0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接