Что не так, если цикл for не может быть завершен в консоли python?

#python-3.x #pandas #dataframe

Вопрос:

Может ли кто-нибудь сказать мне, почему этот цикл for не работает?

 lst = []
c_lst = []
for i in range(182):
    c_lst.append(df.loc[i, 'LE']
    c_lst = 5 * c_lst
    lst = lst   c_lst
 

Я не могу завершить цикл (приглашение больше не появляется) в консоли python и не понимаю, почему это не сработает.

df представляет собой фрейм данных со 182 строками, «ФАЙЛ» — это имя одного из столбцов. Я хочу создать список lst с каждым элементом столбца «ФАЙЛ», который появляется 5 раз lst .

Комментарии:

1. Нужно это… np.repeat(df['LE'].values, 5) ?

2. Отсутствующие родители в строке 4 являются вероятным виновником, как предполагает @rocketsfallonrocketfalls. Но ваш код также может взорваться. Вы действительно хотите дублировать свой результат 5 раз на каждой итерации? 5 * [1] возвращается [1, 1, 1, 1, 1] , затем в следующем цикле у вас будет список длиной 25, затем 125, затем…

3. @MichaelDelgado это была опечатка. Теперь я обновил вопрос.

4. пожалуйста, либо оставьте свой вопрос, как он был, либо удалите его — с вашим редактированием вопросов нет

Ответ №1:

Вместо использования цикла for рассмотрите возможность использования операций с массивами с помощью numpy. numpy.tile Метод повторит весь df.LE вектор, который вы затем можете выровнять numpy.array.ravel .

Использование образца фрейма данных, который насчитывает от 0 до 499:

 In [4]: df = pd.DataFrame({'LE': np.arange(500)})
 

Массив можно повторить 5 раз по горизонтали, затем развернуть, чтобы получить желаемый результат [0, 0, 0, 0, 0, 1, 1, ..., 499, 499, 499, 4999, 499] :

 In [5]: np.tile(df[['LE']], (1, 5)).ravel()
Out[5]: array([  0,   0,   0, ..., 499, 499, 499])
 

Векторизованный метод значительно быстрее:

 
In [11]: %timeit np.tile(df[['LE']], (1, 5)).ravel()
453 µs ± 51.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [12]: %%timeit
    ...: lst = []
    ...: for i in range(len(df)):
    ...:     c_lst = []
    ...:     c_lst.append(df.loc[i, 'LE'])
    ...:     c_lst = 5 * c_lst
    ...:     lst = lst   c_lst
    ...:
4.75 ms ± 57.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
 

Здесь цикл for занимает в 10 раз больше времени. Но для большего массива, например, с 10k элементами, разница действительно проявляется:

 In [13]: df = pd.DataFrame({'LE': np.arange(10000)})

In [14]: %timeit np.tile(df[['LE']], (1, 5)).ravel()
623 µs ± 10.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [15]: %%timeit
    ...: lst = []
    ...: for i in range(len(df)):
    ...:     c_lst = []
    ...:     c_lst.append(df.loc[i, 'LE'])
    ...:     c_lst = 5 * c_lst
    ...:     lst = lst   c_lst
    ...:
609 ms ± 26 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
 

Здесь цикл for в 1000 раз медленнее. Я попробовал это с 1 миллионом элементов, но устал ждать завершения цикла for… хаха.

Ответ №2:

Может быть, это потому, что у вас отсутствует парантез ) в конце 4-й строки, и вы пытаетесь написать код в окне терминала?

Комментарии:

1. Это была опечатка. Да, я пытаюсь манипулировать фреймом данных в интерпретаторе python в окне терминала.

Ответ №3:

Я мог бы найти, что было не так. Код должен быть:

 lst = []
for i in range(182):
    c_lst = []
    c_lst.append(df.loc[i, 'LE'])
    c_lst = 5 * c_lst
    lst = lst   c_lst
 

Таким образом, цикл for может закончиться, и lst все будет так, как я хотел. Спасибо.

Комментарии:

1. да, это было чрезмерное повторение, которое, по — видимому, мешало вам раньше-вы создавали список длины sum_(i in range(182))(5^(i 1))

2. @MichaelDelgado Спасибо тебе! Я удалю этот вопрос. Ты прав.

3. Не могу удалить вопрос, поэтому я оставляю его с ошибками.