Wie erhalte ich einen Wert aus einer Zelle eines Datenrahmens?

344

Ich habe eine Bedingung erstellt, die genau eine Zeile aus meinem Datenrahmen extrahiert:

d2 = df[(df['l_ext']==l_ext) & (df['item']==item) & (df['wn']==wn) & (df['wd']==1)]

Jetzt möchte ich einen Wert aus einer bestimmten Spalte entnehmen:

val = d2['col_name']

Als Ergebnis erhalte ich jedoch einen Datenrahmen, der eine Zeile und eine Spalte enthält ( dh eine Zelle). Es ist nicht das, was ich brauche. Ich brauche einen Wert (eine Float-Nummer). Wie kann ich das bei Pandas machen?

römisch
quelle
1
Wenn Sie einige dieser Antworten ausprobiert haben, aber am Ende eine erhalten haben SettingWithCopyWarning, können Sie in diesem Beitrag eine Erläuterung der Warnung und möglicher Problemumgehungen / Lösungen finden.
CS95

Antworten:

428

Wenn Sie einen DataFrame mit nur einer Zeile haben, greifen Sie auf die erste (einzige) Zeile als Serie mit ilocund dann auf den Wert mit dem Spaltennamen zu:

In [3]: sub_df
Out[3]:
          A         B
2 -0.133653 -0.030854

In [4]: sub_df.iloc[0]
Out[4]:
A   -0.133653
B   -0.030854
Name: 2, dtype: float64

In [5]: sub_df.iloc[0]['A']
Out[5]: -0.13365288513107493
Andy Hayden
quelle
1
@Sophologist beim Betrachten, ich habe keine Ahnung. Die Frage ist etwas seltsam formuliert, aber sie liest sich so, als wäre die erste Hälfte für letztere unerheblich. ( atist eine wirklich schöne Antwort, obwohl ich es seltsam finde, wie es ist ix:))
Andy Hayden
9
@Sophologist Ich stimme zu, dass es lächerlich ist, dass dies erforderlich ist. Es funktioniert auch nicht, wenn Sie versuchen, die Bedingungen inline zu übergeben. my_df.loc[my_df['Col1'] == foo]['Col2']gibt immer noch ein Objekt vom Typ zurück<class 'pandas.core.series.Series'>
user5359531
15
Beachten Sie, dass diese Lösung eine Serie zurückgibt, keinen Wert!
Atte Juvonen
1
@AtteJuvonen Das hängt davon ab, ob Sie Duplikate in Ihrem Index / Ihren Spalten haben (Hinweis bei / iat löst eine Ausnahme mit doppelten Spalten aus, wird ein Problem melden).
Andy Hayden
1
seltsam. Ich lese weiter loc ist für Namen und iloc ist für ganze Zahlen, aber hier ist iloc sowohl für ganze Zahlen als auch für Namen
mLstudent33
205

Dies ist ein schneller Zugriff für Skalare

In [15]: df = pandas.DataFrame(numpy.random.randn(5,3),columns=list('ABC'))

In [16]: df
Out[16]: 
          A         B         C
0 -0.074172 -0.090626  0.038272
1 -0.128545  0.762088 -0.714816
2  0.201498 -0.734963  0.558397
3  1.563307 -1.186415  0.848246
4  0.205171  0.962514  0.037709

In [17]: df.iat[0,0]
Out[17]: -0.074171888537611502

In [18]: df.at[0,'A']
Out[18]: -0.074171888537611502
Jeff
quelle
9
Ich mag diese Antwort sehr. Aber während Sie tun .iloc[-1]['A']können, können Sie nicht tun at[-1,'A'], um den letzten
Zeileneintrag
3
Dies sollte die Antwort sein, da wir keine nutzlose Zeile in den Speicher kopieren, um nur ein Element in den Speicher zu bekommen.
Bormat
3
@hartmut Sie können immer nur tunat[df.index[-1],'A']
cs95
105

Sie können Ihren 1x1-Datenrahmen in ein Numpy-Array verwandeln und dann auf den ersten und einzigen Wert dieses Arrays zugreifen:

val = d2['col_name'].values[0]
Guillaume
quelle
10
Bitte verbessern Sie die Qualität Ihrer Antwort mit etwas mehr Erklärung.
Franck Gamess
Bearbeiten Sie Ihre erste Antwort damit, bevor Sie einen Kommentar erstellen. Vielen Dank
Franck Gamess
2
Ich bevorzuge diese Methode und benutze sie häufig. Wird .get_values()[0]auch verwendet.
Aaronpenne
3
Ich denke, dies ist die beste Antwort, da es keine pandas.series zurückgibt, und es ist die einfachste.
Sean McCarthy
Welchen Vorteil hat dies gegenüber den von Pandas bereitgestellten Methoden?
AMC
28

Die meisten Antworten werden verwendet, ilocwas für die Auswahl nach Position gut ist.

Wenn Sie eine Auswahl nach Etikett benötigen, ist locdies bequemer.

Zum expliziten Abrufen eines Werts (entspricht veraltetem df.get_value ('a', 'A'))

# this is also equivalent to df1.at['a','A']
In [55]: df1.loc['a', 'A'] 
Out[55]: 0.13200317033032932
Shihe Zhang
quelle
18

Ich brauchte den Wert einer Zelle, ausgewählt nach Spalten- und Indexnamen. Diese Lösung hat bei mir funktioniert:

original_conversion_frequency.loc[1,:].values[0]

Natacha
quelle
16

Es sieht nach Änderungen nach Pandas 10.1 / 13.1 aus

Ich habe ein Upgrade von 10.1 auf 13.1 durchgeführt, bevor iloc nicht verfügbar ist.

Erhält jetzt mit 13.1 iloc[0]['label']ein einzelnes Wertearray anstelle eines Skalars.

So was:

lastprice=stock.iloc[-1]['Close']

Ausgabe:

date
2014-02-26 118.2
name:Close, dtype: float64
Zeit ist Liebe
quelle
Ich denke, dies sollte nur bei Serien mit doppelten Einträgen der Fall sein. Ich sehe das nicht. Können Sie ein kleines Beispiel geben, um dies zu demonstrieren?
Andy Hayden
Ich habe Pandas 13.x verwendet, sowohl iloc [] [] als auch iloc [,] geben einen Skalar aus. nur das iloc arbeitet nicht mit negativem Index, wie -1
timeislove
Wenn Sie ein Spielzeugbeispiel geben können, das dies in der Antwort demonstriert, wäre es wirklich hilfreich!
Andy Hayden
5

Die schnellsten / einfachsten Optionen, die ich gefunden habe, sind die folgenden. 501 repräsentiert den Zeilenindex.

df.at[501,'column_name']
df.get_value(501,'column_name')
jroakes
quelle
5
get_valueist jetzt veraltet (v0.21.0 RC1 (13. Oktober 2017)) Referenz ist hier .get_value and .set_value on Series, DataFrame, Panel, SparseSeries, and SparseDataFrame are deprecated in favor of using .iat[] or .at[] accessors (GH15269)
Shihe Zhang
4

ilocFiltern Sie für Pandas 0.10, wo dies nicht verfügbar ist, a DFund rufen Sie die Daten der ersten Zeile für die Spalte ab VALUE:

df_filt = df[df['C1'] == C1val & df['C2'] == C2val]
result = df_filt.get_value(df_filt.index[0],'VALUE')

Wenn mehr als eine Zeile gefiltert ist, erhalten Sie den ersten Zeilenwert. Es gibt eine Ausnahme, wenn der Filter zu einem leeren Datenrahmen führt.

Sergey Sergienko
quelle
3
get_valueist jetzt veraltet (v0.21.0 RC1 (13. Oktober 2017)) Referenz ist hier .get_value and .set_value on Series, DataFrame, Panel, SparseSeries, and SparseDataFrame are deprecated in favor of using .iat[] or .at[] accessors (GH15269)
Shihe Zhang
Aber iatoder atkann nicht den Wert erhalten , basierend auf den Spaltennamen.
Sivabudh
4

Ich bin mir nicht sicher, ob dies eine gute Praxis ist, aber ich habe festgestellt, dass ich auch nur den Wert erhalten kann, indem ich die Serie als besetze float .

z.B

rate

3 0,042679

Name: Arbeitslosenquote, Typ: float64

float(rate)

0,0426789

Michael Wei
quelle
Funktioniert das auch mit einer Multi-Element-Serie?
Praxiteles
0

Es muss nicht kompliziert sein:

val = df.loc[df.wd==1, 'col_name'].values[0]
Eduardo Freitas
quelle
-1
df_gdp.columns

Index ([u'Country ', u'Country Code', u'Indicator Name ', u'Indicator Code', u'1960 ', u'1961', u'1962 ', u'1963', u'1964 ' , u'1965 ', u'1966', u'1967 ', u'1968', u'1969 ', u'1970', u'1971 ', u'1972', u'1973 ', u'1974' , u'1975 ', u'1976', u'1977 ', u'1978', u'1979 ', u'1980', u'1981 ', u'1982', u'1983 ', u'1984' , u'1985 ', u'1986', u'1987 ', u'1988', u'1989 ', u'1990', u'1991 ', u'1992', u'1993 ', u'1994' , u'1995 ', u'1996', u'1997 ', u'1998', u'1999 ', u'2000',u'2001 ', u'2002', u'2003 ', u'2004', u'2005 ', u'2006', u'2007 ', u'2008', u'2009 ', u'2010', u'2011 ', u'2012', u'2013 ', u'2014', u'2015 ', u'2016'], dtype = 'object')

df_gdp[df_gdp["Country Code"] == "USA"]["1996"].values[0]

8100000000000.0

Su Tingxuan
quelle
4
Ist das eine Antwort oder eine Frage?
Vega
4
Willkommen bei Stack Overflow! Vielen Dank für das Code-Snippet, das möglicherweise nur begrenzte, sofortige Hilfe bietet. Eine richtige Erklärung würde ihren langfristigen Wert erheblich verbessern, indem sie beschreibt, warum dies eine gute Lösung für das Problem ist, und es für zukünftige Leser mit anderen ähnlichen Fragen nützlicher machen. Bitte bearbeiten Sie Ihre Antwort, um eine Erklärung hinzuzufügen, einschließlich der von Ihnen getroffenen Annahmen.
September
Trotz der negativen Stimmen hat mir diese Antwort tatsächlich geholfen.
CONvid19