Панды - как передать переменную как столбец во вложенный цикл? - PullRequest
0 голосов
/ 05 января 2019

У меня есть вложенный цикл, в который я пытаюсь передать значения из списка, но он не распознает значение списка. Если я заменю value[col] на любое значение списка, например value['OpNo'], это сработает. Есть ли какая-то конкретная оболочка или что-то, что мне нужно, в списке значений или в коде назначения?

Я пробовал списки, такие как col_list = ["'OpNo'", "'StationNo'", "'Spindle'", "'OpDescription'"], и упаковывал col выноску, как value[[col]]

Приведенный ниже код получает следующее исключение: KeyError: 'OpNo'

row_indexer = 0
col_indexer = 1
iloc_indexer = 0
count_row = operationData.shape[0]
col_list = ['OpNo', 'StationNo', 'Spindle', 'OpDescription']
while row_indexer < count_row:    
    value = operationData.iloc[[row_indexer],[iloc_indexer]]
    for col in col_list:
        value = value[col].values[0]
        wb['OneOpSheet'].cell(row = (row_indexer + 12), column = (col_indexer + 1)).value = value
        col_indexer = (col_indexer + 1)
    row_indexer = (row_indexer + 1)
    iloc_indexer = (iloc_indexer + 1)

Ответы [ 3 ]

0 голосов
/ 05 января 2019

Я не уверен, поможет ли это вам точно, но, возможно, оно поможет вам в правильном направлении. Вы можете использовать Pandas.DataFrame.itertuples () для запуска по всем строкам в вашем фрейме данных, выбирая значения по мере необходимости.

Я пошел немного дальше и создал быстрый словарь меток столбцов, чтобы помочь синхронизировать вложенные циклы.

Я пытался комментировать, где это необходимо, но если вы что-то не поняли, дайте мне знать!

import pandas as pd
import openpyxl
wb = load_workbook(filename='./generic_workbook_name.xlsx')

# Created smoe data for a dataframe.
fake_data_dict = {
    'OpNo':['1','2','3','4',],
    'StationNo':['11','22','33','44',],
    'Spindle':['S1','S2','S3','S4',],
    'OpDescription':['This','is','a','description',]
    }

# Create the dataframe.
data = pd.DataFrame(fake_data_dict)

Наш фрейм данных:

  OpNo StationNo Spindle OpDescription
0    1        11      S1          This
1    2        22      S2            is
2    3        33      S3             a
3    4        44      S4   description

Остальная часть сценария:

col_list = ['OpNo','StationNo','Spindle','OpDescription']


# Create a column label dictionary; Add 1 to index for Excel cells
col_dict = {i+1:v for i, v in enumerate(col_list)}

# Iterate over each row
for idx, row in enumerate(data.itertuples(), start = 1):
    # For each key in our column dictionary [0, 1, 2, 3]
    for key in col_dict.keys():
        print('Row: {a}\n\tColumn: {b}\n\t\tValue: {c}'.format(a = idx, b = key,
                                                               # Reduce the index by 1; Get column name based on key value.
                                                               c = data.loc[idx - 1, col_dict[key]]))

Выход:

Row: 1
    Column: 1
        Value: 1
Row: 1
    Column: 2
        Value: 11
Row: 1
    Column: 3
        Value: S1
Row: 1
    Column: 4
        Value: This
Row: 2
    Column: 1
        Value: 2
Row: 2
    Column: 2
        Value: 22
Row: 2
    Column: 3
        Value: S2
Row: 2
    Column: 4
        Value: is
Row: 3
    Column: 1
        Value: 3
Row: 3
    Column: 2
        Value: 33
Row: 3
    Column: 3
        Value: S3
Row: 3
    Column: 4
        Value: a
Row: 4
    Column: 1
        Value: 4
Row: 4
    Column: 2
        Value: 44
Row: 4
    Column: 3
        Value: S4
Row: 4
    Column: 4
        Value: description

Имея это в виду, это может упростить ваш сценарий:

for idx, row in enumerate(data.itertuples(), start = 1):
    for key in col_dict.keys():
        wb['OneOpSheet'].cell(row = (idx + 11), column = (key + 1)).value = data.loc[idx - 1, col_dict[key]]
0 голосов
/ 06 января 2019

Мне нужно было поместить обе команды в цикл for и сбросить пару индексаторов после того, как это закончится. Вложенный ниже цикл выполняет то, что мне нужно:

while row_indexer < count_row:    
    for col in col_list:
        value = operationData.iloc[[row_indexer],[iloc_indexer]]
        value = value[col].values[0]
        wb['OneOpSheet'].cell(row = (row_indexer + 12), column = (col_indexer + 2)).value = value
        col_indexer += 1
        iloc_indexer += 1
    row_indexer += 1
    iloc_indexer = 0
    col_indexer = 0
0 голосов
/ 05 января 2019

Я думаю, value = operationData.iloc[[row_indexer],[iloc_indexer]] возвращает фрейм данных. Попробуйте value = value.loc[col].values[0].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...