Подтвердить что ты не робот

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
4b9b3361

Ответ 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]]