python - functions - Grupo de pandas por: cómo obtener una unión de cadenas
python pandas download windows (4)
Es posible que pueda usar la función de aggregate
(o agg
) para concatenar los valores. (Código no probado)
df.groupby(''A'')[''B''].agg(lambda col: ''''.join(col))
Tengo un marco de datos como este:
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 !
Vocación
In [10]: print df.groupby("A")["B"].sum()
regresará
A
1 1.615586
2 0.421821
3 0.463468
4 0.643961
Ahora me gustaría hacer "lo mismo" para la columna "C". Como esa columna contiene cadenas, sum () no funciona (aunque podría pensar que concatenaría las cadenas). Lo que realmente me gustaría ver es una lista o un conjunto de cadenas para cada grupo, es decir,
A
1 {This, string}
2 {is, !}
3 {a}
4 {random}
He estado tratando de encontrar formas de hacer esto.
Series.unique () ( http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.unique.html ) no funciona, aunque
df.groupby("A")["B"]
es un
pandas.core.groupby.SeriesGroupBy object
así que esperaba que cualquier método de la Serie funcionara. ¿Algunas ideas?
Puede usar el método de aplicar para aplicar una función arbitraria a los datos agrupados. Entonces, si quieres un conjunto, aplica set
. Si quieres una lista, aplica la 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
Si quieres algo más, solo escribe una función que haga lo que quieras y luego apply
eso.
una solución simple sería:
>>> df.groupby([''A'',''B'']).c.unique().reset_index()
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
Cuando aplica su propia función, no hay exclusiones automáticas de columnas no numéricas. Sin embargo, esto es más lento que la aplicación de .sum()
al 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
por defecto se concatena
In [9]: df.groupby(''A'')[''C''].apply(lambda x: x.sum())
Out[9]:
A
1 Thisstring
2 is!
3 a
4 random
dtype: object
Puedes hacer más o menos lo que quieras
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
Haciendo esto un grupo completo de cuadros a la vez. La clave es devolver una 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}