pandas DataFrame,如何将函数应用于特定列?

44

我已经阅读了 DataFrame.apply的文档

DataFrame.apply(func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds)¶ 沿着DataFrame的输入轴应用函数。

那么,我怎样才能将函数应用到特定列呢?

In [1]: import pandas as pd
In [2]: data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
In [3]: df = pd.DataFrame(data)
In [4]: df
Out[4]: 
   A  B  C
0  1  4  7
1  2  5  8
2  3  6  9
In [5]: def addOne(v):
...:        v += 1
...:        return v
...: 
In [6]: df.apply(addOne, axis=1)
Out[6]: 
   A  B   C
0  2  5   8
1  3  6   9
2  4  7  10

我想将df['A']中的每个值加1,而不是所有列。如何使用DataFrame.apply实现?

谢谢帮助!


1
尽可能避免使用apply。如果您不确定是否需要使用它,那么您可能不需要。我建议查看何时应该在代码中使用pandas apply()? - cs95
1
@coldspeed 很好,问题和答案深入。 - GoingMyWay
4个回答

62

1
can we apply same function at a time on both A and B. - dondapati
2
@dondapati 当然可以,你只需在addOne函数内部添加v['B'] += 1。当axis=1时,Pandas的apply函数会将每一行作为v传入。 - su79eu7k

20

一个简单的方法是:

df['A'] = df['A'].apply(lambda x: x+1)

我按照你的建议进行了以下操作:df['A'] = df['A'].apply(lambda x: datetime.fromtimestamp(float(x)/1000.))但是出现了以下提示信息:“正在尝试在 DataFrame 的切片副本上设置值。 请改用 .loc[row_indexer,col_indexer] = value。 "有什么建议吗? - Catarina Nogueira
1
@Catarina Nogueira 请在最后添加.copy(),例如apply(...).copy()。 - Nosey
我不认为这是一个好的解决方案。你正在对DataFrame进行变异,同时迭代自身。我建议首先复制一份DataFrame。请参考这里: https://pandas.pydata.org/docs/user_guide/gotchas.html#gotchas-udf-mutation - Paul
1
@Paul 好建议。在执行 UDF 函数之前进行复制可以避免一些意外行为。 - Felix Feng

4

对于其他需要能够进行管道传输的解决方案:

identity = lambda x: x

def transform_columns(df, mapper):
    return df.transform(
        {
            **{
                column: identity
                for column in df.columns
            },
            **mapper
        }
    )

# you can monkey-patch it on the pandas DataFrame (but don't have to, see below)
pd.DataFrame.transform_columns = transform_columns

(
    pd.DataFrame(data)
    .rename(columns={'A': 'A1'})   # just to demonstrate the motivation
    .transform_columns({'A1': add_one})
)

这也允许:
pd.DataFrame(data).transform_columns({
    'A': add_one,
    'B': add_two,
})

如果你不想使用猴子补丁(DataFrame monkey-patch),你可以通过pipe来使用它:

pd.DataFrame(data).pipe(transform_columns, {'A': add_one})

不过,如果pandas能够自然地支持这一点,那就太好了。

上面的代码片段是CC0。


2
您可以使用lambda函数与.apply()方法来解决这类问题。假设您的数据框如下所示:
A | B | C
----------
1 | 4 | 7
2 | 5 | 8
3 | 6 | 9

您想要应用的函数:
def addOne(v):
v += 1
return v

所以,如果你像这样编写代码:
df['A'] = df.apply(lambda x: addOne(x.A), axis=1)

你将获得:

A | B | C
----------
2 | 4 | 7
3 | 5 | 8
4 | 6 | 9

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