it-swarm.asia

بانداس groupby: كيفية الحصول على اتحاد السلاسل

لديّ قاعدة بيانات مثل هذا:

   A         B       C
0  1  0.749065    This
1  2  0.301084      is
2  3  0.463468       a
3  4  0.643961  random
4  1  0.866521  string
5  2  0.120737       !

دعوة

In [10]: print df.groupby("A")["B"].sum()

سيعود

A
1    1.615586
2    0.421821
3    0.463468
4    0.643961

الآن أود أن أفعل "نفس الشيء" للعمود "C". نظرًا لأن هذا العمود يحتوي على سلاسل ، فإن sum () لا يعمل (على الرغم من أنك قد تعتقد أنه سيكون متسلسلاً بالسلسلة). ما أود حقاً رؤيته هو قائمة أو مجموعة من السلاسل لكل مجموعة ، أي.

A
1    {This, string}
2    {is, !}
3    {a}
4    {random}

لقد كنت أحاول إيجاد طرق للقيام بذلك.

Series.unique () ( http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.unique.html ) لا يعمل ، على الرغم من

df.groupby("A")["B"]

هو

pandas.core.groupby.SeriesGroupBy object

لذلك كنت آمل أن تعمل أي طريقة سلسلة. أيه أفكار؟

96
Anne
In [4]: df = read_csv(StringIO(data),sep='\s+')

In [5]: df
Out[5]: 
   A         B       C
0  1  0.749065    This
1  2  0.301084      is
2  3  0.463468       a
3  4  0.643961  random
4  1  0.866521  string
5  2  0.120737       !

In [6]: df.dtypes
Out[6]: 
A      int64
B    float64
C     object
dtype: object

عندما تقوم بتطبيق وظيفتك الخاصة ، لا توجد استثناءات تلقائية للأعمدة غير الرقمية. هذا أبطأ من تطبيق .sum() على groupby

In [8]: df.groupby('A').apply(lambda x: x.sum())
Out[8]: 
   A         B           C
A                         
1  2  1.615586  Thisstring
2  4  0.421821         is!
3  3  0.463468           a
4  4  0.643961      random

sum بشكل افتراضي يسلسل

In [9]: df.groupby('A')['C'].apply(lambda x: x.sum())
Out[9]: 
A
1    Thisstring
2           is!
3             a
4        random
dtype: object

يمكنك أن تفعل الكثير ما تريد

In [11]: df.groupby('A')['C'].apply(lambda x: "{%s}" % ', '.join(x))
Out[11]: 
A
1    {This, string}
2           {is, !}
3               {a}
4          {random}
dtype: object

القيام بذلك مجموعة الإطار بأكمله في وقت واحد. المفتاح هو إرجاع Series

def f(x):
     return Series(dict(A = x['A'].sum(), 
                        B = x['B'].sum(), 
                        C = "{%s}" % ', '.join(x['C'])))

In [14]: df.groupby('A').apply(f)
Out[14]: 
   A         B               C
A                             
1  2  1.615586  {This, string}
2  4  0.421821         {is, !}
3  3  0.463468             {a}
4  4  0.643961        {random}
147
Jeff

يمكنك استخدام الأسلوب apply لتطبيق دالة اعتباطية على البيانات المجمعة. لذلك إذا كنت تريد مجموعة ، فطبق set. إذا كنت تريد قائمة ، فطبق list.

>>> d
   A       B
0  1    This
1  2      is
2  3       a
3  4  random
4  1  string
5  2       !
>>> d.groupby('A')['B'].apply(list)
A
1    [This, string]
2           [is, !]
3               [a]
4          [random]
dtype: object

إذا كنت تريد شيئًا آخر ، فما عليك سوى كتابة وظيفة تقوم بما تريد ثم apply.

52
BrenBarn

قد تتمكن من استخدام دالة aggregate (أو agg) لسَلسَلة القيم. (كود غير مجرب)

df.groupby('A')['B'].agg(lambda col: ''.join(col))
18
voithos

حل بسيط سيكون:

>>> df.groupby(['A','B']).c.unique().reset_index()
6
UserYmY

إذا كنت تريد الكتابة فوق العمود B في إطار البيانات ، فيجب أن يعمل هذا:

    df = df.groupby('A',as_index=False).agg(lambda x:'\n'.join(x))
2
Amit

يمكنك تجربة هذا:

df.groupby('A').agg({'B':'sum','C':'-'.join})
2
user3241146