“ValueError: Lengte van waarden komt niet overeen met de lengte van de index” wanneer u probeert kolomwaarden een PANDAS CARDBY

Ik heb een dataframe:

      A         C         D
0    one  0.410599 -0.205158
1    one  0.144044  0.313068
2    one  0.333674 -0.742165
3  three  0.761038 -2.552990
4  three  1.494079  2.269755
5    two  1.454274 -0.854096
6    two  0.121675  0.653619
7    two  0.443863  0.864436

Laten we aannemen dat Ade ankerkolom is. Ik wil nu elke groepswaarde slechts één keer weergeven, bovenaan:

       A         C         D
0    one  0.410599 -0.205158
1         0.144044  0.313068
2         0.333674 -0.742165
3  three  0.761038 -2.552990
4         1.494079  2.269755
5    two  1.454274 -0.854096
6         0.121675  0.653619
7         0.443863  0.864436

Dit is wat ik heb bedacht:

df['A'] = df.groupby('A', as_index=False)['A']\
        .apply(lambda x: x.str.replace('.*', '').set_value(0, x.values[0])).values

Mijn strategie was om een ​​groep te doen en vervolgens alle waarden in te stellen op een lege tekenreeks dan de eerste. Dit lijkt niet te werken, omdat ik krijg:

ValueError: Length of values does not match length of index

Wat betekent dat de uitgang die ik krijg onjuist is. Alle ideeën / suggesties / verbeteringen welkom.

Ik moet hieraan toevoegen dat ik een oplossing probeer te generaliseren die waarden boven OF onder OF in het midden van elke groep kan onderscheiden, dus ik zou meer de voorkeur geven aan een oplossing die me daarbij helpt (om te begrijpen, de het bovenstaande voorbeeld laat zien hoe waarden alleen bovenaan elke groepkunnen worden geselecteerd, maar ik wil een oplossing generaliseren waarmee ik ze onderaan of in het midden kan selecteren).


Antwoord 1, autoriteit 100%

Uw methode werkte niet vanwege de indexfout. Wanneer u groepeert op ‘A’, wordt de index ook op dezelfde manier weergegeven in de gegroepeerde gegevens. Aangezien set_value(0)de juiste index niet kon vinden, maakt het een nieuw objectmet die index. Dat is de reden waarom er een lengte mismatch was.

1 repareren
reset_index(drop=True)

df['A'] = df.groupby('A')['A'].apply(lambda x: x.str.replace('.*', '')\
                      .reset_index(drop=True).set_value(0, x.values[0])).values
df
      A         C         D
0    one  0.410599 -0.205158
1         0.144044  0.313068
2         0.333674 -0.742165
3  three  0.761038 -2.552990
4         1.494079  2.269755
5    two  1.454274 -0.854096
6         0.121675  0.653619
7         0.443863  0.864436

2 repareren
set_value

set_valueheeft een derde parameter genaamd takeabledie bepaalt hoe de index wordt behandeld. Het is standaard False, maar instellen op Truewerkte voor mijn geval.

Naast Zero’s oplossingen, is de oplossing voor het isoleren van waarden in het midden van hun groepen als volgt:

df.A = df.groupby('A'['A'].apply(lambda x: x.str.replace('.*', '')\
                           .set_value(len(x) // 2, x.values[0], True)).values 
df
       A         C         D
0         0.410599 -0.205158
1    one  0.144044  0.313068
2         0.333674 -0.742165
3         0.761038 -2.552990
4  three  1.494079  2.269755
5         1.454274 -0.854096
6    two  0.121675  0.653619
7         0.443863  0.864436

Antwoord 2, autoriteit 29%

Omdat de waarden zijn gesorteerd, gebruikt u de duplicatedmethode voor de eerste en laatste gevallen.


Blijf op de eerste plaats

In [4233]: df.loc[df.A.duplicated(keep='first'), 'A'] = ''
In [4234]: df
Out[4234]:
       A         C         D
0    one  0.410599 -0.205158
1         0.144044  0.313068
2         0.333674 -0.742165
3  three  0.761038 -2.552990
4         1.494079  2.269755
5    two  1.454274 -0.854096
6         0.121675  0.653619
7         0.443863  0.864436

Houd het laatste

In [4236]: df.loc[df.A.duplicated(keep='last'), 'A'] = ''
In [4237]: df
Out[4237]:
       A         C         D
0         0.410599 -0.205158
1         0.144044  0.313068
2    one  0.333674 -0.742165
3         0.761038 -2.552990
4  three  1.494079  2.269755
5         1.454274 -0.854096
6         0.121675  0.653619
7    two  0.443863  0.864436

Other episodes