Pandas DataFrame столбец в список
Я вынимаю подмножество данных из столбца на основе условий в другом столбце.
Я могу вернуть правильные значения, но он находится в pandas.core.frame.DataFrame. Как преобразовать это в список?
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
Ответы
Ответ 1
Используйте .values
, чтобы получить numpy.array
, а затем .tolist()
, чтобы получить список.
Например:
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]})
Результат:
>>> df['a'].values.tolist()
[1, 3, 5, 7, 4, 5, 6, 4, 7, 8, 9]
или вы можете просто использовать
>>> df['a'].tolist()
[1, 3, 5, 7, 4, 5, 6, 4, 7, 8, 9]
Чтобы удалить дубликаты, вы можете выполнить одно из следующих действий:
>>> df['a'].drop_duplicates().values.tolist()
[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]
Ответ 2
Я хотел бы прояснить несколько вещей:
- Как указывали другие ответы, проще всего использовать
pandas.Series.tolist()
. Я не уверен, почему главный голосующий ответ
приводит к использованию с помощью pandas.Series.values.tolist()
, поскольку, насколько я могу судить, он добавляет синтаксис/путаницу без каких-либо дополнительных преимуществ.
-
tst[lookupValue][['SomeCol']]
- это кадр данных (как указано в
вопрос), а не ряд (как указано в комментарии к вопросу). Это связано с тем, что tst[lookupValue]
является фреймворком данных, а нарезать его с помощью [['SomeCol']]
запрашивает
список столбцов (список, который имеет длину 1), в результате чего возвращается датафрейм. если ты
удалите дополнительный набор скобок, как в
tst[lookupValue]['SomeCol']
, тогда вы просите только об этом
столбец, а не список столбцов, и таким образом вы получите серию назад.
- Вам нужна серия, чтобы использовать
pandas.Series.tolist()
, поэтому вы должны
в этом случае обязательно пропустите второй набор скобок. FYI, если вы
когда-либо в конечном итоге с одним столбцом кадра данных, что легко избежать
например, вы можете использовать pandas.DataFrame.squeeze()
, чтобы преобразовать его в
серии.
-
tst[lookupValue]['SomeCol']
получает подмножество определенного столбца через
цепной нарезкой. Он срезает один раз, чтобы получить фрейм данных с определенными рядами
слева, а затем снова срезает, чтобы получить определенный столбец. Вы можете получить
прочь с ним здесь, так как вы просто читаете, а не пишете, но
правильный способ сделать это tst.loc[lookupValue, 'SomeCol']
(который возвращает серию).
- Используя синтаксис из # 4, вы можете сделать все в одной строке:
ID = tst.loc[tst['SomeCol'] == 'SomeValue', 'SomeCol'].tolist()
Демо-код:
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)
Результат:
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'>
Ответ 3
Вы можете использовать pandas.Series.tolist
например:.
import pandas as pd
df = pd.DataFrame({'a':[1,2,3], 'b':[4,5,6]})
Run:
>>> df['a'].tolist()
Вы получите
>>> [1, 2, 3]
Ответ 4
Вышеприведенное решение хорошо, если все данные имеют одинаковый тип. Массовые массивы представляют собой однородные контейнеры. Когда вы выполняете df.values
, выход представляет собой numpy array
. Поэтому, если в данных есть int
и float
, тогда вывод будет либо иметь int
, либо float
, и столбцы потеряют свой исходный тип dtype.
Рассмотрим df
a b
0 1 4
1 2 5
2 3 6
a float64
b int64
Итак, если вы хотите сохранить оригинальный dtype, вы можете сделать что-то вроде
row_list = df.to_csv(None, header=False, index=False).split('\n')
это вернет каждую строку в виде строки.
['1.0,4', '2.0,5', '3.0,6', '']
Затем разделите каждую строку, чтобы получить список списка. Каждый элемент после разбиения является юникодом. Нам нужно преобразовать требуемый тип данных.
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]]