529 Stimmen

Holen Sie den ersten Zeilenwert einer angegebenen Spalte

Dies scheint eine lächerlich einfache Frage zu sein ... aber ich sehe nicht die einfache Antwort, die ich erwartet habe.

Wie also erhalte ich den Wert in einer n-ten Zeile einer gegebenen Spalte in Pandas? (Ich bin insbesondere am ersten Wert interessiert, aber wäre auch an einer allgemeineren Vorgehensweise interessiert).

Zum Beispiel, wenn ich den Wert 1.2 in Btime als Variable abrufen möchte.

Was ist der richtige Weg, dies zu tun?

>>> df_test
    ATime   X   Y   Z   Btime  C   D   E
0    1.2  2  15   2    1.2  12  25  12
1    1.4  3  12   1    1.3  13  22  11
2    1.5  1  10   6    1.4  11  20  16
3    1.6  2   9  10    1.7  12  29  12
4    1.9  1   1   9    1.9  11  21  19
5    2.0  0   0   0    2.0   8  10  11
6    2.4  0   0   0    2.4  10  12  15

821voto

unutbu Punkte 769083

Um die i-te Zeile auszuwählen, verwenden Sie iloc:

In [31]: df_test.iloc[0]
Out[31]: 
ATime     1.2
X         2.0
Y        15.0
Z         2.0
Btime     1.2
C        12.0
D        25.0
E        12.0
Name: 0, dtype: float64

Um den i-ten Wert in der Btime-Spalte auszuwählen, könnten Sie Folgendes verwenden:

In [30]: df_test['Btime'].iloc[0]
Out[30]: 1.2

Es gibt einen Unterschied zwischen df_test['Btime'].iloc[0] (empfohlen) und df_test.iloc[0]['Btime']:

DataFrames speichern Daten in spaltenbasierten Blöcken (wobei jeder Block ein einzelnes dtype hat). Wenn Sie zuerst nach Spalte auswählen, kann eine Ansicht zurückgegeben werden (was schneller als eine Kopie ist) und das ursprüngliche dtype bleibt erhalten. Im Gegensatz dazu kopiert Pandas die Daten in eine neue Series mit dem Objekt-Dtype, wenn Sie zuerst nach Zeile auswählen und der DataFrame Spalten mit unterschiedlichen Dtypes hat. Das Auswählen von Spalten ist daher ein wenig schneller als das Auswählen von Zeilen. Obwohl also df_test.iloc[0]['Btime'] funktioniert, ist df_test['Btime'].iloc[0] ein wenig effizienter.

Es gibt einen großen Unterschied zwischen den beiden im Hinblick auf die Zuweisung. df_test['Btime'].iloc[0] = x wirkt sich auf df_test aus, aber df_test.iloc[0]['Btime'] möglicherweise nicht. Lesen Sie unten eine Erklärung, warum. Da ein subtiler Unterschied in der Reihenfolge der Indizierung einen großen Unterschied im Verhalten ausmacht, ist es besser, die Einzelindizierungs-Zuweisung zu verwenden:

df.iloc[0, df.columns.get_loc('Btime')] = x

df.iloc[0, df.columns.get_loc('Btime')] = x (empfohlen):

Die empfohlene Methode zum Zuweisen neuer Werte zu einem DataFrame ist es, verkettete Indizierung zu vermeiden und stattdessen die Methode zu verwenden, die von andrew gezeigt wird,

df.loc[df.index[n], 'Btime'] = x

oder

df.iloc[n, df.columns.get_loc('Btime')] = x

Die letztere Methode ist etwas schneller, da df.loc die Zeilen- und Spaltenbezeichnungen in positionale Indizes umwandeln muss, daher ist etwas weniger Konvertierung erforderlich, wenn Sie stattdessen df.iloc verwenden.


df['Btime'].iloc[0] = x funktioniert, ist jedoch nicht empfohlen:

Obwohl dies funktioniert, nutzt es die Art und Weise, wie DataFrames derzeit implementiert sind. Es gibt keine Garantie dafür, dass Pandas dies in Zukunft auch so umsetzen muss. Insbesondere wird dies ausgenutzt, dass (derzeit) df['Btime'] immer eine Ansicht zurückgibt (keine Kopie), sodass df['Btime'].iloc[n] = x verwendet werden kann, um einen neuen Wert an der nth-Stelle der Btime-Spalte von df zuzuweisen.

Da Pandas keine expliziten Garantien darüber macht, wann Indexer eine Ansicht anstelle einer Kopie zurückgeben, lösen Zuweisungen, die verkettete Indizierungen verwenden, im Allgemeinen immer eine SettingWithCopyWarning aus, obwohl in diesem Fall die Zuweisung erfolgreich ist und df modifiziert:

In [22]: df = pd.DataFrame({'foo':list('ABC')}, index=[0,2,1])
In [24]: df['bar'] = 100
In [25]: df['bar'].iloc[0] = 99
/home/unutbu/data/binky/bin/ipython:1: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self._setitem_with_indexer(indexer, value)

In [26]: df
Out[26]: 
  foo  bar
0   A   99  <-- Zuweisung erfolgreich
2   B  100
1   C  100

df.iloc[0]['Btime'] = x funktioniert nicht:

Im Gegensatz dazu funktioniert eine Zuweisung mit df.iloc[0]['bar'] = 123 nicht, da df.iloc[0] eine Kopie zurückgibt:

In [66]: df.iloc[0]['bar'] = 123
/home/unutbu/data/binky/bin/ipython:1: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

In [67]: df
Out[67]: 
  foo  bar
0   A   99  <-- Zuweisung fehlgeschlagen
2   B  100
1   C  100

Warnung: Ich hatte zuvor df_test.ix[i, 'Btime'] vorgeschlagen. Dies garantiert jedoch nicht, dass Sie den i-ten Wert erhalten, da ix zuerst nach dem Label und nicht nach der Position indiziert. Wenn der DataFrame also einen Ganzzahlindex hat, der nicht in geordneter Folge ab 0 sortiert ist, gibt die Verwendung von ix[i] die Zeile mit dem Label i zurück, anstelle der i-ten Zeile. Zum Beispiel,

In [1]: df = pd.DataFrame({'foo':list('ABC')}, index=[0,2,1])

In [2]: df
Out[2]: 
  foo
0   A
2   B
1   C

In [4]: df.ix[1, 'foo']
Out[4]: 'C'

47voto

Abdulrahman Bres Punkte 2375

Ein weiterer Weg, dies zu tun:

first_value = df['Btime'].values[0]

Dieser Weg scheint schneller zu sein als die Verwendung von .iloc:

In [1]: %timeit -n 1000 df['Btime'].values[20]
5,82 µs ± 142 ns pro Schleife (Mittelwert ± Standardabweichung von 7 Durchläufen, 1000 Schleifen pro Durchlauf)

In [2]: %timeit -n 1000 df['Btime'].iloc[20]
29,2 µs ± 1,28 µs pro Schleife (Mittelwert ± Standardabweichung von 7 Durchläufen, 1000 Schleifen pro Durchlauf)

37voto

andrew Punkte 1733

Beachten Sie, dass die Antwort von @unutbu korrekt ist, bis Sie den Wert auf etwas Neues setzen möchten, dann funktioniert es nicht, wenn Ihr DataFrame eine Ansicht ist.

In [4]: df = pd.DataFrame({'foo':list('ABC')}, index=[0,2,1])
In [5]: df['bar'] = 100
In [6]: df['bar'].iloc[0] = 99
/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas-0.16.0_19_g8d2818e-py2.7-macosx-10.9-x86_64.egg/pandas/core/indexing.py:118: SettingWithCopyWarning:
Es wird versucht, einen Wert auf eine Kopie eines Ausschnitts aus einem DataFrame zu setzen

Weitere Informationen finden Sie in der Dokumentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self._setitem_with_indexer(indexer, value)

Ein weiterer Ansatz, der sowohl beim Setzen als auch beim Abrufen konsistent funktioniert, ist:

In [7]: df.loc[df.index[0], 'foo']
Out[7]: 'A'
In [8]: df.loc[df.index[0], 'bar'] = 99
In [9]: df
Out[9]:
  foo  bar
0   A   99
2   B  100
1   C  100

14voto

nikhil Punkte 141
  1. df.iloc[0].head(1) - Nur der erste Datensatz aus der gesamten ersten Zeile.
  2. df.iloc[0] - Die gesamte erste Zeile in der Spalte.

13voto

Mykola Zotko Punkte 11977

Um auf einen einzelnen Wert zuzugreifen, können Sie die Methode iat verwenden, die viel schneller ist als iloc:

df['Btime'].iat[0]

Sie können auch die Methode take verwenden:

df['Btime'].take(0)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X