it-swarm.com.de

Pandas - Ermittelt den ersten Zeilenwert einer bestimmten Spalte

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

Wie erhalte ich den Wert in einer n-ten Zeile einer bestimmten Spalte in Pandas? (Ich interessiere mich besonders für die erste Reihe, würde mich aber auch für eine allgemeinere Praxis interessieren).

Nehmen wir zum Beispiel an, ich möchte den Wert 1,2 in Btime als Variable ziehen.

Was ist der richtige Weg, um 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
209
Ahmed Haque

Um die Zeile ith 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 Spalte Btime auszuwählen, können 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 einen einzelnen D-Typ hat). Wenn Sie zuerst nach Spalte auswählen, kann ein view zurückgegeben werden (was schneller ist als das Zurückgeben einer Kopie) und der ursprüngliche d-Typ bleibt erhalten. Wenn Sie dagegen zuerst eine Zeile auswählen und der DataFrame Spalten mit unterschiedlichen Datentypen enthält, werden die Daten mit Pandas copy in eine neue Serie von Objektdatentypen kopiert. Das Auswählen von Spalten ist also etwas schneller als das Auswählen von Zeilen. Obwohl df_test.iloc[0]['Btime'] funktioniert, ist df_test['Btime'].iloc[0] ein bisschen effizienter.

Es gibt einen großen Unterschied zwischen den beiden, wenn es um die Zuordnung geht. df_test['Btime'].iloc[0] = x beeinflusst df_test, df_test.iloc[0]['Btime'] jedoch möglicherweise nicht. Im Folgenden finden Sie eine Erklärung, warum. Da ein geringfügiger Unterschied in der Reihenfolge der Indizierung einen großen Unterschied im Verhalten bewirkt, ist es besser, eine einzelne Indizierungszuweisung 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 lautet Vermeiden einer verketteten Indizierung und stattdessen benutze die Methode gezeigt von andrew ,

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 Spaltenbeschriftungen in Positionsindizes konvertieren muss. Wenn Sie also stattdessen df.iloc verwenden, ist etwas weniger Konvertierung erforderlich.


df['Btime'].iloc[0] = x funktioniert, wird aber nicht empfohlen:

Obwohl dies funktioniert, nutzt es die Art und Weise, wie DataFrames derzeit ​​implementiert sind. Es gibt keine Garantie dafür, dass Pandas in Zukunft so arbeiten muss. Insbesondere wird die Tatsache ausgenutzt, dass df['Btime'] (derzeit) immer eine Ansicht (keine Kopie) zurückgibt, sodass df['Btime'].iloc[n] = x zum Zuweisen eines neuen Werts bei verwendet werden kann Die n-te Stelle der Btime -Spalte von df.

Da Pandas keine expliziten Garantien dafür gibt, wann Indexer eine Ansicht im Vergleich zu einer Kopie zurückgeben, wird bei Zuweisungen mit verketteter Indexierung im Allgemeinen immer ein SettingWithCopyWarning ausgegeben, obwohl die Zuweisung in diesem Fall erfolgreich ist, df zu ändern:

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  <-- assignment succeeded
2   B  100
1   C  100

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

Im Gegensatz dazu funktioniert die 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  <-- assignment failed
2   B  100
1   C  100

Warnung : Ich hatte zuvor df_test.ix[i, 'Btime'] vorgeschlagen. Es kann jedoch nicht garantiert werden, dass Sie den Wert ith erhalten, da ix versucht, nach label zu indizieren, bevor versucht wird, nach position zu indizieren. Wenn der DataFrame also einen Ganzzahlindex hat, der nicht in sortierter Reihenfolge ab 0 beginnt, gibt die Verwendung von ix[i] die Zeile labeli und nicht den ith zurück. Reihe. 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'
330
unutbu

Beachten Sie, dass die Antwort von @unutbu korrekt ist, bis Sie den Wert auf etwas Neues setzen möchten. Wenn es sich bei Ihrem Datenframe um eine Ansicht handelt, funktioniert dies nicht.

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:
A value is trying to be set on a copy of a slice from a DataFrame

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

Ein anderer Ansatz, der sowohl mit dem Setzen als auch mit dem Erhalten 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
23
andrew

Ein anderer 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 per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [2]: %timeit -n 1000 df['Btime'].iloc[20]
29.2 µs ± 1.28 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
9
  1. df.iloc[0].head(1) - Erster Datensatz nur aus der gesamten ersten Zeile.
  2. df.iloc[0] - Ganze erste Zeile in Spalte.
9
nikhil

Wenn Sie im Allgemeinen die ersten N Zeilen aus der J Spalte aus pandas dataframe abholen möchten, ist der beste Weg, dies zu tun:

data = dataframe[0:N][:,J]
4
anis

Um beispielsweise den Wert aus Spalte 'Test' und Zeile 1 zu erhalten, funktioniert ti wie folgt

df[['test']].values[0][0]

as nur df[['test']].values[0] gibt ein Array zurück

0
Alex Ortner

Eine andere Möglichkeit, die erste Zeile abzurufen, in der der Index gespeichert ist:

x = df.first('d') # Returns the first day. '3d' gives first three days.
0
Hunaphu