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_list
methode.
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:
- 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 vanpandas.Series.values.tolist()
want voor zover ik weet, voegt het syntaxis/verwarring toe zonder extra voordeel. tst[lookupValue][['SomeCol']]
is een dataframe (zoals vermeld in de
vraag), geen serie (zoals vermeld in een opmerking bij de vraag). Dit komt omdattst[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.- 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 upandas.DataFrame.squeeze()
gebruiken om het te converteren naar
een serie. 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 istst.loc[lookupValue, 'SomeCol']
(die een reeks retourneert).- 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.values
doet, is de uitvoer een numpy array
. Dus als de gegevens int
en float
bevatten, dan heeft de uitvoer int
of float
en 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]]