Pandas 组依据的奇怪行为 - 对字符串列进行转换
Strange Behavior With Pandas Group By - Transform On String Columns
我遇到了 Pandas .groupby() 和 .transform() 的奇怪行为。这是生成数据集的代码:
df = pd.DataFrame({"Name" : ["Alice", "Bob", "Mallory", "Mallory", "Bob" , "Mallory"] ,
"Random_Number": [1223344, 373293832, 32738382392, 7273283232, 8239329, 23938832],
"City" : ["Seattle", "Seattle", "Portland", "Seattle", "Seattle", "Portland"]})
这是我为 transform() 编写的函数。
# this function will attach each value in string col with the number of elements in the each city group
# if the col type is not an object, then return 0 for all rows.
def some(x):
if x.dtype == 'object':
return x + '--' + str(len(x))
else:
return 0
然后我将我的函数与转换一起使用 - 完美地工作并得到我想要的。
df_2 = stack.groupby(["City"])['Name','Random_Number'].transform(some)
然而,当我将 col 的顺序从 ['Name','Random_Number']
切换到 ['Random_Number','Name']
时,奇怪的事情发生了
df_2 = stack.groupby(["City"])['Random_Number','Name'].transform(some)
当您查看 'Name'
列中的单元格时,似乎 pandas 将所有内容多次放入一个单元格中:
df_2.iloc[0,1]
# Return:
# 0 Alice--4
# 1 Bob--4
# 3 Mallory--4
# 4 Bob--4
# Name: Name, dtype: object
为什么会这样?
问题出在您的return
。
如果 x.dtype == 'object'
那么你 return 一个系列所以你的 transform
聚合 不会减少 (return 是与原始长度相同)。如果采用另一条路径,return 是单个标量 0
,pandas 将其视为缩减(return 是每组单个值)。
因为您的聚合在缩减方面有所不同,无论内部 pandas
用来找出要采用的路径以及如何将其带回原始 DataFrame,都会根据您的列顺序感到困惑。当 'Random_Number'
是第一个时,它检查函数,发现函数减少并采用一条路径,但如果 'Name'
首先出现,它检查,发现函数没有减少并采用另一条路径进行计算。
您可以通过确保两个 returns 不减少
来解决这个问题
def some(x):
if x.dtype == 'object':
return x + '--' + str(len(x))
else:
return [0]*len(x)
df.groupby('City')[['Random_Number','Name']].transform(some)
# Random_Number Name
#0 0 Alice--4
#1 0 Bob--4
#2 0 Mallory--2
#3 0 Mallory--4
#4 0 Bob--4
#5 0 Mallory--2
df.groupby('City')[['Name', 'Random_Number']].transform(some)
# Name Random_Number
#0 Alice--4 0
#1 Bob--4 0
#2 Mallory--2 0
#3 Mallory--4 0
#4 Bob--4 0
#5 Mallory--2 0
我遇到了 Pandas .groupby() 和 .transform() 的奇怪行为。这是生成数据集的代码:
df = pd.DataFrame({"Name" : ["Alice", "Bob", "Mallory", "Mallory", "Bob" , "Mallory"] ,
"Random_Number": [1223344, 373293832, 32738382392, 7273283232, 8239329, 23938832],
"City" : ["Seattle", "Seattle", "Portland", "Seattle", "Seattle", "Portland"]})
这是我为 transform() 编写的函数。
# this function will attach each value in string col with the number of elements in the each city group
# if the col type is not an object, then return 0 for all rows.
def some(x):
if x.dtype == 'object':
return x + '--' + str(len(x))
else:
return 0
然后我将我的函数与转换一起使用 - 完美地工作并得到我想要的。
df_2 = stack.groupby(["City"])['Name','Random_Number'].transform(some)
然而,当我将 col 的顺序从 ['Name','Random_Number']
切换到 ['Random_Number','Name']
df_2 = stack.groupby(["City"])['Random_Number','Name'].transform(some)
当您查看 'Name'
列中的单元格时,似乎 pandas 将所有内容多次放入一个单元格中:
df_2.iloc[0,1]
# Return:
# 0 Alice--4
# 1 Bob--4
# 3 Mallory--4
# 4 Bob--4
# Name: Name, dtype: object
为什么会这样?
问题出在您的return
。
如果 x.dtype == 'object'
那么你 return 一个系列所以你的 transform
聚合 不会减少 (return 是与原始长度相同)。如果采用另一条路径,return 是单个标量 0
,pandas 将其视为缩减(return 是每组单个值)。
因为您的聚合在缩减方面有所不同,无论内部 pandas
用来找出要采用的路径以及如何将其带回原始 DataFrame,都会根据您的列顺序感到困惑。当 'Random_Number'
是第一个时,它检查函数,发现函数减少并采用一条路径,但如果 'Name'
首先出现,它检查,发现函数没有减少并采用另一条路径进行计算。
您可以通过确保两个 returns 不减少
来解决这个问题def some(x):
if x.dtype == 'object':
return x + '--' + str(len(x))
else:
return [0]*len(x)
df.groupby('City')[['Random_Number','Name']].transform(some)
# Random_Number Name
#0 0 Alice--4
#1 0 Bob--4
#2 0 Mallory--2
#3 0 Mallory--4
#4 0 Bob--4
#5 0 Mallory--2
df.groupby('City')[['Name', 'Random_Number']].transform(some)
# Name Random_Number
#0 Alice--4 0
#1 Bob--4 0
#2 Mallory--2 0
#3 Mallory--4 0
#4 Bob--4 0
#5 Mallory--2 0