在预排序的 DataFrame 上使用 pandas groupby 的迭代顺序

Eri*_*mar 4 python group-by pandas pandas-groupby

情况

我正在使用基于特定列中的值的特定分类器对 DataFrame 中的行进行分类。我的目标是根据特定条件将结果附加到一个新列或另一列。代码看起来像这样:

df = pd.DataFrame({'A': [list with classifier ids],  # Only 3 ids, One word strings
                   'B': [List of text to be classified],  # Millions of unique rows, lines of text around 5-25 words long
                   'C': [List of the old classes]}  # Hundreds of possible classes, four digit integers stored as strings

df.sort_values('A', inplace=True)

new_col1, new_col2 = [], []
for name, group in df.groupby('A', sort=False):
    classifier = classy_dict[name]
    vectors = vectorize(group.B.values)

    preds = classifier.predict(vectors)
    scores = classifier.decision_function(vectors)

    for tup in zip(preds, scores, group.C.values):
        if tup[2] == tup[0]:
            new_col1.append(np.nan)
            new_col2.append(tup[2])

        else:
            new_col1.append(str(classifier.classes_[tup[1].argsort()[-5:]]))
            new_col2.append(np.nan)

df['D'] = new_col1
df['E'] = new_col2
Run Code Online (Sandbox Code Playgroud)

问题

我担心它groupby不会像我期望的那样以自上而下的外观顺序进行迭代。文档中sort=False未涵盖的迭代顺序

我的期望

我在这里寻找的只是一些肯定,groupby('col', sort=False)它确实以我期望的自上而下的外观顺序进行迭代。如果有更好的方法来完成所有这些工作,我们不胜感激。

这是我用来测试我的sort=False迭代顺序理论的代码:

from numpy.random import randint
import pandas as pd
from string import ascii_lowercase as lowers

df = pd.DataFrame({'A': [lowers[randint(3)] for _ in range(100)],
                   'B': randint(10, size=100)})

print(df.A.unique())  # unique values in order of appearance per the docs

for name, group in df.groupby('A', sort=False):
    print(name)
Run Code Online (Sandbox Code Playgroud)

编辑:上面的代码使它看起来好像它以我期望的方式行事,但我想要一些更不可否认的证据,如果有的话。

ALo*_*llz 6

是的,当您通过时sort=False,会保留首次出现的顺序。该groupby源代码是有点不透明的,但有一个功能,groupby.ngroup这充分回答了这个问题,因为它直接告诉你在迭代发生的顺序。

def ngroup(self, ascending=True):
    """
    Number each group from 0 to the number of groups - 1.
    This is the enumerative complement of cumcount.  Note that the
    numbers given to the groups match the order in which the groups
    would be seen when iterating over the groupby object, not the
    order they are first observed.
    ""
Run Code Online (Sandbox Code Playgroud)

来自@coldspeed 的数据

df['sort=False'] = df.groupby('col', sort=False).ngroup()
df['sort=True'] = df.groupby('col', sort=True).ngroup()
Run Code Online (Sandbox Code Playgroud)

输出:

    col  sort=False  sort=True
0   16           0          7
1    1           1          0
2   10           2          5
3   20           3          8
4    3           4          2
5   13           5          6
6    2           6          1
7    5           7          3
8    7           8          4
Run Code Online (Sandbox Code Playgroud)

sort=False您根据第一次出现进行迭代时,sort=True它会对组进行排序,然后进行迭代。