gpt4 book ai didi

python - Pandas DataFrame.agg 在选择缺少类别后生成多索引

转载 作者:行者123 更新时间:2023-12-04 07:36:54 25 4
gpt4 key购买 nike

我仍在研究一个可重现的示例,但不幸的是,我是 Pandas 的绝对初学者,我对自己做错了什么感到迷茫。这种行为似乎是 Pandas 1.2.4 中的一个错误。
我有两个数据框,files_df它给出了几个存储库中源代码文件的类型和复杂性,以及 proj_df这给出了项目及其上次更新的时间。
我试图按复杂性为每种语言选择前两个项目,它看起来像这样:

def largest(x):
return (
# Pick the top two rows in each language (from the groupby) by scc_complexity
x.nlargest(2, 'scc_complexity')
# Combine the proj_repo values (we don't actually care about scc_complexity at this point)
.agg({'proj_repo': lambda y: '<br>'.join(y.values)})
)

max_proj = (
# Pick the language and complexity columns
files_df[['scc_lang', 'scc_complexity', 'proj_repo']]
# Sum scc_complexity by language and repo
.groupby(['scc_lang', 'proj_repo'], observed=True).sum()
.reset_index()
)

max_proj = (
max_proj
# Select only repos updated in the last two years
.loc[max_proj['proj_repo'].isin(proj_df.loc[proj_df['last_author_time'] > '2019-05-01', 'proj_repo'])]
# Now pick the top repos by language complexity
.groupby('scc_lang').apply(largest)
)
这应该产生一个带有 scc_lang 的框架作为它的索引和 proj_repo作为其唯一的列,但它会产生以下形状:
<class 'pandas.core.frame.DataFrame'>
MultiIndex: 151 entries, ('ASP', 'proj_repo') to ('XML Schema (min)', 'proj_repo')
Data columns (total 2 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 0 151 non-null object
1 proj_repo 0 non-null object
dtypes: object(2)
memory usage: 8.7+ KB
MultiIndex([( 'ASP', 'proj_repo'),
( 'Autoconf', 'proj_repo'),
( 'BASH', 'proj_repo'),
( 'Batch', 'proj_repo'),
...
也就是说,现在有一个多索引,而 proj_info column 现在是一个名为 0 的列,以及 proj_info列现在是空的。
现在是真正奇怪的部分。如果删除 .loc[],此代码会生成正确的形状选择来自 max_proj .对于我的一生,我无法弄清楚为什么进行选择会改变结果的形状。我无法用一个完整的小例子来重现结果。
我会继续试验,如果我学到任何有趣的东西,我会在这里报告。
轻微更新:我发现删除 observed=True似乎也产生了正确的形状——所以这可能与缺少 key 有关?
更大的更新 :我设法重现它,是的,它确实与丢失的 key 有关,但我不确定如何:
tdf = pd.DataFrame([['lang1', 1, 'ab'],
['lang2', 2, 'cd'],
['lang2', 4, 'cd'],
['lang2', 3, 'ef'],
['lang2', 4, 'gh'],
['lang3', 2, 'ef']
],
columns=['lang', 'size', 'name']).astype({'lang': 'category'}, copy=False).set_index('lang')

d = tdf.groupby(['lang', 'name'], observed=True).sum().reset_index()
d = d.loc[d['name'].isin(pd.Series(['ab','cd','gh']))].groupby('lang').apply(lambda x: x.agg({'name': lambda y: ' '.join(y.values)}))
display(d)
d.info()



0
姓名






lang1
姓名
AB
NaN

lang2
姓名
光碟
NaN

<class 'pandas.core.frame.DataFrame'>
MultiIndex: 2 entries, ('lang1', 'name') to ('lang2', 'name')
Data columns (total 2 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 0 2 non-null object
1 name 0 non-null object
dtypes: object(2)
memory usage: 356.0+ bytes
删除 'ab' 或 'ef' 名称会触发此操作,这意味着它与缺少的类别有关。事实上,将列类型改回 object也修复了这个问题。所以似乎我误解了类别......
另一个更新 :我已经设法将其减少到这两行:
tdf2 = pd.DataFrame([['a', 'boof']], columns=['lang', 'name']).astype({'lang': pd.CategoricalDtype(['a', 'b'])})
display(tdf2.groupby('lang').apply(lambda x: x.agg({'name': lambda y: y.values})))
我们现在非常小。删除上述代码的几乎任何位都会导致生成的数据框对齐到正确的形状。
我们这里有一个 agg 应用于由 .groupby('lang') 生成的空数据帧。 ,它会恢复已从数据中删除的类别。在 apply() 内部重新加入的结果似乎有些奇怪.
这里的一个新发现是返回 y.values来自 apply() lambda 是其中的一部分:如果我返回 y (系列)相反,奇怪的结构不会发生。

最佳答案

最后,我找到了。奇怪的结构结果是因为空数据帧上的单列 agg 的结果是一个数据帧,但如果该数据帧有行,结果是一个系列:

tdf2 = pd.DataFrame([], columns=['lang', 'name'])
print(type(tdf2.agg({'name': lambda y: y.values})))

tdf2 = pd.DataFrame([['a', 'boof']], columns=['lang', 'name'])
print(type(tdf2.agg({'name': lambda y: y.values})))
<class 'pandas.core.frame.DataFrame'>
<class 'pandas.core.series.Series'>
groupby的 apply()返回奇怪的结构,因为它试图将两者结合起来:
tdf2 = pd.DataFrame([['a', 'boof'], ['b', 'toop']], columns=['lang', 'name'])
print(tdf2.groupby('lang').apply(lambda x: x['name'] if x.iloc[0,0] == 'a' else x))
           0 lang  name
lang
a 0 boof NaN NaN
b 1 NaN b toop
我不知道我是否会称其为错误。这当然是令人惊讶的行为,以及一般的程序 should not be surprising .
更新 : 提交为 https://github.com/pandas-dev/pandas/issues/41672 .
更新 2 :现在我了解了类别的工作原理,对原始代码的最终修复是添加 observed=True在应用之前添加到 groupby,消除空数据帧。

关于python - Pandas DataFrame.agg 在选择缺少类别后生成多索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67697606/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com