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

Как превратить блок данных в ряд списков?

Мне приходилось делать это несколько раз, и я всегда разочарован. У меня есть dataframe:

df = pd.DataFrame([[1, 2, 3, 4], [5, 6, 7, 8]], ['a', 'b'], ['A', 'B', 'C', 'D'])

print df

   A  B  C  D
a  1  2  3  4
b  5  6  7  8

Я хочу превратить df в:

pd.Series([[1, 2, 3, 4], [5, 6, 7, 8]], ['a', 'b'])

a    [1, 2, 3, 4]
b    [5, 6, 7, 8]
dtype: object

Я пробовал

df.apply(list, axis=1)

Который только возвращает меня к тому же df

Каков удобный/эффективный способ сделать это?

4b9b3361

Ответ 1

Вы можете сначала преобразовать DataFrame в numpy array с помощью values, затем преобразовать в список и создать последнее Series с индексом df если требуется более быстрое решение:

print (pd.Series(df.values.tolist(), index=df.index))
a    [1, 2, 3, 4]
b    [5, 6, 7, 8]
dtype: object

Сроки с небольшим DataFrame:

In [76]: %timeit (pd.Series(df.values.tolist(), index=df.index))
1000 loops, best of 3: 295 µs per loop

In [77]: %timeit pd.Series(df.T.to_dict('list'))
1000 loops, best of 3: 685 µs per loop

In [78]: %timeit df.T.apply(tuple).apply(list)
1000 loops, best of 3: 958 µs per loop

и с большим:

from string import ascii_letters
letters = list(ascii_letters)
df = pd.DataFrame(np.random.choice(range(10), (52 ** 2, 52)),
                  pd.MultiIndex.from_product([letters, letters]),
                  letters)

In [71]: %timeit (pd.Series(df.values.tolist(), index=df.index))
100 loops, best of 3: 2.06 ms per loop

In [72]: %timeit pd.Series(df.T.to_dict('list'))
1 loop, best of 3: 203 ms per loop

In [73]: %timeit df.T.apply(tuple).apply(list)
1 loop, best of 3: 506 ms per loop

Ответ 2

pandas очень сложно заставить сделать dataframes удобным. Таким образом, он интерпретирует списки и массивы как вещи, которые вы хотите разделить на столбцы. Я не собираюсь жаловаться, это почти всегда полезно.

Я сделал это одним из двух способов.

Вариант 1:

# Only works with a non MultiIndex
# and its slow, so don't use it
df.T.apply(tuple).apply(list)

Вариант 2:

pd.Series(df.T.to_dict('list'))

Оба дают вам:

a    [1, 2, 3, 4]
b    [5, 6, 7, 8]
dtype: object

Однако Вариант 2 масштабируется лучше.


Timing

задано df

введите описание изображения здесь

намного больше df

from string import ascii_letters
letters = list(ascii_letters)
df = pd.DataFrame(np.random.choice(range(10), (52 ** 2, 52)),
                  pd.MultiIndex.from_product([letters, letters]),
                  letters)

Результаты для df.T.apply(tuple).apply(list) ошибочны, потому что это решение не работает над MultiIndex.

введите описание изображения здесь

Ответ 3

Преобразование данных в список преобразования

List_name =df_name.values.tolist()