#python #python-3.x #pandas
#python #python-3.x #pandas
Вопрос:
У меня есть фрейм данных с именами col ‘a’, ‘b’, ‘c’
#Input
import pandas as pd
list_of_dicts = [
{'a' : 0, 'b' : 4, 'c' : 3},
{'a' : 1, 'b' : 1, 'c' : 2 },
{'a' : 0, 'b' : 0, 'c' : 0 },
{'a' : 1, 'b' : 0, 'c' : 3 },
{'a' : 2, 'b' : 1, 'c' : 0 }
]
df = pd.DataFrame(list_of_dicts)
#Input DataFrame
-----|------|------|-----|
| a | b | c |
-----|------|------|-----|
0 | 0 | 4 | 3 |
1 | 1 | 1 | 2 |
2 | 0 | 0 | 0 |
3 | 1 | 0 | 3 |
4 | 2 | 1 | 0 |
Я хочу уменьшить широкий фрейм данных до одного столбца с именами столбцов
в качестве значений фрейма данных, умноженных на соответствующие значения строк. Операция должна выполняться по строкам.
#Output
| Values |
-----------------
0 | b |
1 | b |
2 | b |
3 | b |
4 | c |
5 | c |
6 | c |
7 | a |
8 | b |
9 | c |
10 | c |
11 | a |
12 | c |
13 | c |
14 | c |
15 | a |
17 | a |
18 | b |
Объяснение:
Строка 0 во входном фрейме данных содержит 4 ‘b’ и 3 ‘c’, поэтому первые семь элементов выходного фрейма данных — bbbbccc
Строка 1 аналогично имеет 1 ‘a’, 1 ‘b’ и 2 ‘c’, поэтому на выходе будет abcc в качестве следующих 4 элементов
Строка 2 имеет 0 в поперечнике, поэтому будет полностью пропущена.
Порядок вывода очень важен, например, в первой строке ‘4’ b и 3 ‘c’, поэтому выходной фрейм данных должен быть bbbbccc, потому что столбец ‘b’ предшествует столбцу ‘c’. Операция должна выполняться по строкам слева направо.
Я пытаюсь найти эффективный способ для достижения этой цели. Реальный набор данных слишком велик для меня, чтобы вычислить. Пожалуйста, предоставьте решение python3.
Комментарии:
1. Это то, чего вы действительно хотите? Означает ли тот факт, что [{‘a’:0,’b’:4,’c’:3}] и [{‘a’:0,’b’:4,’c’:2},{‘a’:0,’b’:0,’c’:1}] выдача того же результата не вызывает проблемы?
2. Важен порядок вывода. Например, первая строка как 4 ‘b’ и 3 ‘c’, тогда выходной фрейм данных должен иметь первые 7 строк как bbbbccc. Вывод не может быть bcbcbcb или любой другой комбинацией.
3. Но, насколько я понимаю из вашего описания, мои два примера будут иметь точно такой же результат: bbbbccc. Просто проверяю, что это то, что вы ожидаете
4. О, я понял ваш вопрос. Нет, это не вызывает проблемы. Извините, я не понял вашу проблему раньше. Оба должны давать одинаковый результат.
5. Мне нужно было бы подумать об этом некоторое время, чтобы посмотреть, есть ли какой-либо способ использования кода изменения формы pandas ( pandas.pydata.org/pandas-docs/stable/user_guide/reshaping.html ) делать то, что вы хотите, но мне было бы интересно, откуда берутся ваши данные и будет ли проще передавать входные данные потоком, а не загружать все в памятьне так, как вы этого хотите в первую очередь.
Ответ №1:
Сложите данные (вы также можете расплавить) и отбросьте строки, где количество равно нулю. Наконец, используйте numpy.repeat для создания нового массива и создайте из него свой новый фрейм данных.
reshape = df.stack().droplevel(0).loc[lambda x: x != 0]
pd.DataFrame(np.repeat(reshape.index, reshape), columns=['values'])
values
0 b
1 b
2 b
3 b
4 c
5 c
6 c
7 a
8 b
9 c
10 c
11 a
12 c
13 c
14 c
15 a
16 a
17 b
Комментарии:
1. Большое вам спасибо! Это решает задачу!
Ответ №2:
Я не думаю, что pandas что-то дает вам в этом процессе, и особенно, если у вас большой объем данных, вы не хотите считывать все это в память и перерабатывать в другую большую структуру данных.
import csv
with open('input.csv', 'r') as fh:
reader = csv.DictReader(fh)
for row in reader:
for key in reader.headers:
value = int(row[key])
for i in range(value):
print(key)