Pandas DataFrame-kolom om weer te geven

Ik haal een subset van gegevens uit een kolom op basis van voorwaarden in een andere kolom waaraan wordt voldaan.

Ik kan de juiste waarden terugkrijgen, maar het staat in pandas.core.frame.DataFrame. Hoe converteer ik dat naar een lijst?

import pandas as pd
tst = pd.read_csv('C:\\SomeCSV.csv')
lookupValue = tst['SomeCol'] == "SomeValue"
ID = tst[lookupValue][['SomeCol']]
#How To convert ID to a list

Antwoord 1, autoriteit 100%

U kunt de Series.to_listmethode.

Bijvoorbeeld:

import pandas as pd
df = pd.DataFrame({'a': [1, 3, 5, 7, 4, 5, 6, 4, 7, 8, 9],
                   'b': [3, 5, 6, 2, 4, 6, 7, 8, 7, 8, 9]})
print(df['a'].to_list())

Uitvoer:

[1, 3, 5, 7, 4, 5, 6, 4, 7, 8, 9]

Als u duplicaten wilt verwijderen, kunt u een van de volgende dingen doen:

>>> df['a'].drop_duplicates().to_list()
[1, 3, 5, 7, 4, 6, 8, 9]
>>> list(set(df['a'])) # as pointed out by EdChum
[1, 3, 4, 5, 6, 7, 8, 9]

Antwoord 2, autoriteit 10%

Ik wil graag een paar dingen verduidelijken:

  1. Zoals andere antwoorden al hebben aangegeven, is het eenvoudigste om te gebruiken
    pandas.Series.tolist(). Ik weet niet zeker waarom het best gestemde antwoord
    begint met het gebruik van pandas.Series.values.tolist()want voor zover ik weet, voegt het syntaxis/verwarring toe zonder extra voordeel.
  2. tst[lookupValue][['SomeCol']]is een dataframe (zoals vermeld in de
    vraag), geen serie (zoals vermeld in een opmerking bij de vraag). Dit komt omdat tst[lookupValue]een dataframe is en als je het in plakjes snijdt met [['SomeCol']]wordt gevraagd om
    een lijst met kolommen (die lijst die toevallig een lengte heeft van 1), wat resulteert in een dataframe dat wordt geretourneerd. als jij
    verwijder de extra set beugels, zoals in
    tst[lookupValue]['SomeCol'], dan vraag je om precies die ene
    kolom in plaats van een lijst met kolommen, en zo krijg je een reeks terug.
  3. Je hebt een serie nodig om pandas.Series.tolist()te gebruiken, dus je moet
    sla in dit geval zeker de tweede set haakjes over. Ter info, als je
    ooit eindigen met een dataframe met één kolom dat niet gemakkelijk te vermijden is
    op deze manier kunt u pandas.DataFrame.squeeze()gebruiken om het te converteren naar
    een serie.
  4. tst[lookupValue]['SomeCol']krijgt een subset van een bepaalde kolom via
    geketend snijden. Het snijdt één keer om een dataframe te krijgen met alleen bepaalde rijen
    links, en dan snijdt het opnieuw om een bepaalde kolom te krijgen. Je kan krijgen
    weg ermee hier, want je bent alleen maar aan het lezen, niet aan het schrijven, maar
    de juiste manier om dit te doen is tst.loc[lookupValue, 'SomeCol'](die een reeks retourneert).
  5. Als je de syntaxis van #4 gebruikt, zou je redelijkerwijs alles in één regel kunnen doen: ID = tst.loc[tst['SomeCol'] == 'SomeValue', 'SomeCol'].tolist()

Democode:

import pandas as pd
df = pd.DataFrame({'colA':[1,2,1],
                   'colB':[4,5,6]})
filter_value = 1
print "df"
print df
print type(df)
rows_to_keep = df['colA'] == filter_value
print "\ndf['colA'] == filter_value"
print rows_to_keep
print type(rows_to_keep)
result = df[rows_to_keep]['colB']
print "\ndf[rows_to_keep]['colB']"
print result
print type(result)
result = df[rows_to_keep][['colB']]
print "\ndf[rows_to_keep][['colB']]"
print result
print type(result)
result = df[rows_to_keep][['colB']].squeeze()
print "\ndf[rows_to_keep][['colB']].squeeze()"
print result
print type(result)
result = df.loc[rows_to_keep, 'colB']
print "\ndf.loc[rows_to_keep, 'colB']"
print result
print type(result)
result = df.loc[df['colA'] == filter_value, 'colB']
print "\ndf.loc[df['colA'] == filter_value, 'colB']"
print result
print type(result)
ID = df.loc[rows_to_keep, 'colB'].tolist()
print "\ndf.loc[rows_to_keep, 'colB'].tolist()"
print ID
print type(ID)
ID = df.loc[df['colA'] == filter_value, 'colB'].tolist()
print "\ndf.loc[df['colA'] == filter_value, 'colB'].tolist()"
print ID
print type(ID)

Resultaat:

df
   colA  colB
0     1     4
1     2     5
2     1     6
<class 'pandas.core.frame.DataFrame'>
df['colA'] == filter_value
0     True
1    False
2     True
Name: colA, dtype: bool
<class 'pandas.core.series.Series'>
df[rows_to_keep]['colB']
0    4
2    6
Name: colB, dtype: int64
<class 'pandas.core.series.Series'>
df[rows_to_keep][['colB']]
   colB
0     4
2     6
<class 'pandas.core.frame.DataFrame'>
df[rows_to_keep][['colB']].squeeze()
0    4
2    6
Name: colB, dtype: int64
<class 'pandas.core.series.Series'>
df.loc[rows_to_keep, 'colB']
0    4
2    6
Name: colB, dtype: int64
<class 'pandas.core.series.Series'>
df.loc[df['colA'] == filter_value, 'colB']
0    4
2    6
Name: colB, dtype: int64
<class 'pandas.core.series.Series'>
df.loc[rows_to_keep, 'colB'].tolist()
[4, 6]
<type 'list'>
df.loc[df['colA'] == filter_value, 'colB'].tolist()
[4, 6]
<type 'list'>

Antwoord 3, autoriteit 7%

U kunt pandas.Series.tolist

. gebruiken

bijv.:

import pandas as pd
df = pd.DataFrame({'a':[1,2,3], 'b':[4,5,6]})

Uitvoeren:

>>> df['a'].tolist()

Je krijgt

>>> [1, 2, 3]

Antwoord 4

De bovenstaande oplossing is goed als alle gegevens van hetzelfde dtype zijn. Numpy-arrays zijn homogene containers. Als je df.valuesdoet, is de uitvoer een numpy array. Dus als de gegevens inten floatbevatten, dan heeft de uitvoer intof floaten de kolommen zullen hun oorspronkelijke dtype verliezen.
Overweeg df

a  b 
0  1  4
1  2  5 
2  3  6 
a    float64
b    int64 

Dus als je het originele dtype wilt behouden, kun je zoiets doen als

row_list = df.to_csv(None, header=False, index=False).split('\n')

dit retourneert elke rij als een tekenreeks.

['1.0,4', '2.0,5', '3.0,6', '']

Verdeel vervolgens elke rij om een lijst met lijsten te krijgen. Elk element na splitsing is een unicode. We moeten het vereiste gegevenstype converteren.

def f(row_str): 
  row_list = row_str.split(',')
  return [float(row_list[0]), int(row_list[1])]
df_list_of_list = map(f, row_list[:-1])
[[1.0, 4], [2.0, 5], [3.0, 6]]

Other episodes