pandas:将函数应用于dataframe列中的每个唯一元素,并合并输出

时间:2016-01-23 16:43:08

标签: python pandas

让我们考虑一个数据框:

np.random.seed(123)
df = pd.DataFrame({"x": np.random.random(size=10)})
df["y"] = np.where(df.x < 0.5, 0, 1)

输出:

          x  y
0  0.696469  1
1  0.286139  0
2  0.226851  0
3  0.551315  1
4  0.719469  1
5  0.423106  0
6  0.980764  1
7  0.684830  1
8  0.480932  0
9  0.392118  0

我想添加一个名为id的新列:

          x  y    id
0  0.696469  1  id_1
1  0.286139  0  id_0
2  0.226851  0  id_0
3  0.551315  1  id_1
4  0.719469  1  id_1
5  0.423106  0  id_0
6  0.980764  1  id_1
7  0.684830  1  id_1
8  0.480932  0  id_0
9  0.392118  0  id_0

我发现我可以使用apply函数

df.groupby("y").apply(lambda d: "id_%d" % d.name)

输出:

0    id_0
1    id_1
dtype: object

Q1:如何将apply功能的输出合并回原始数据框?

Q2:是否有更优雅的方式添加id列?

3 个答案:

答案 0 :(得分:1)

您只需添加一个列:

df['id'] = df['y'].apply(lambda d: "id_%d" % d)

返回:

          x  y    id
0  0.696469  1  id_1
1  0.286139  0  id_0
2  0.226851  0  id_0
3  0.551315  1  id_1
4  0.719469  1  id_1
5  0.423106  0  id_0
6  0.980764  1  id_1
7  0.684830  1  id_1
8  0.480932  0  id_0
9  0.392118  0  id_0

编辑: 如果您需要使用:

func = df.groupby("y").apply(lambda d: "id_%d" % d.name)

您稍后可以使用map

df['id'] = df['y'].map(func)

答案 1 :(得分:0)

您在没有apply()的情况下直接使用该列:

>>> df['id'] = 'id_' + df.y.astype(str)
>>> df

          x  y    id
0  0.696469  1  id_1
1  0.286139  0  id_0
2  0.226851  0  id_0
3  0.551315  1  id_1
4  0.719469  1  id_1
5  0.423106  0  id_0
6  0.980764  1  id_1
7  0.684830  1  id_1
8  0.480932  0  id_0
9  0.392118  0  id_0

答案 2 :(得分:0)

此方法隔离唯一值,将函数应用于这些唯一值,然后将它们合并到父数据帧中。它有效地替换了原始列。

import pandas as pd

# DEFINE INPUTS:
df = pd.read_csv("https://j." + "mp/iriscsv")
mycol = "species"
myfunction = lambda v: print(f"Applying once to {v}") or v.title()

# APPLY TO UNIQUE VALUES ONLY, AND CREATE MAPPING:
mycol_unique = df[mycol].drop_duplicates()
mycol_unique_new = mycol_unique.apply(myfunction)
df_map = pd.concat([mycol_unique, mycol_unique_new], axis="columns")
mycol_new = f"{mycol}_new"
df_map.columns = [mycol, mycol_new]
del mycol_unique, mycol_unique_new

# MERGE:
assert mycol_new not in df.columns
df[mycol] = df[[mycol]].merge(df_map, how="left", on=mycol).set_index(mycol.index)[mycol_new]
del df_map

非常重要的是,请注意上面.set_index(mycol.index)的使用,否则将导致结果不正确。这是必要的,因为df.merge会重置返回的数据帧的索引。