Более простая альтернатива np.where() для изменения значения строки pandas

#python #pandas #numpy #dataframe

#python #pandas #numpy #фрейм данных

Вопрос:

У меня есть df фрейм данных, подобный этому:

             id    year      x1     x2  ...        x15        
0         1000  1973.0   3.277  0.297  ...        NaN        
1         1000  1974.0   3.494  0.010  ...        NaN        
2         1000  1975.0   5.335  0.180  ...  27.686086  
3         1000  1976.0   7.143  0.348  ...  25.982902  
4         1000  1977.0   3.503  0.234  ...  16.120394  
       ...     ...     ...    ...  ...        ...        
140008  184740  1983.0  12.728  0.000  ...  37.367403  
140009  184740  1984.0   9.219  0.000  ...  29.819767  
140010  187839  1986.0  -0.016  0.000  ...        NaN      
140011  187839  1987.0  -0.416  0.000  ...        NaN       
140012  187839  1988.0  -0.925  0.000  ...  -0.578135 
 

Для эмпирических работ мне нужно выполнить некоторые вычисления по строкам, скажем, они содержатся в функции foo(row) , значение которой нужно поместить в столбец x15 и которая возвращает V . foo(row) использует значения некоторых столбцов row плюс значение x15 предыдущей строки. Процедура, которую я должен выполнить, является итеративной, т.Е. Она начинается с присвоения нулевого значения x15 (для его инициализации в первом периоде), применяется foo(row) к первой строке, устанавливает соответствующее значение x15 , равное выходному, а затем повторяет процесс для следующей строки. Это должно выполняться последовательно (поочередно year ) для каждого идентификатора ( id ). Чтобы привести пример:

 def foo(row):
    row['x15']=(calculations involving the columns of that row) (other calculations of the previous value of x15) 
 

Решение, о котором я думал, заключается в том, чтобы применить foo(row) в первой строке (для каждого id ) и присвоить ее значение x15 ; создание новых столбцов нулей, «x16« и использование

 row['x16']=np.where((df['id']==row['id'])amp;(df['year']>=row['year']),V, row['x16'])
 

Последняя строка написана таким образом, чтобы я мог указать foo(row) так

 def foo(row):
    row['x15']=(calculations involving the columns of that row) (other calculations using x16) 
 

Скопировав выходные foo(row) x16 данные into за все годы, равные тому, который я применяю к функции, для той же фирмы, я могу сохранить функцию foo(row) только для строк, и, таким образом, я могу затем
df.apply(foo, axis=1) и я получаю то, что хочу.

Проблема с этим подходом заключается в том, что у меня довольно много np.where() вычислений, подобных только что упомянутому, и я увидел, что это создает узкие места в моей общей функции из-за поиска по индексу, который я использую в нем (df['id']==row['id'])amp;(df['year']>=row['year']) . Есть ли у вас какие-либо предложения о том, как выполнить то же самое, что описано выше, с другим подходом, чтобы я мог пропустить np.where() часть и ускорить все это?

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

1. Я не читал весь вопрос, но вы можете использовать df.query('<column> == <value>')

2. A where подходит, когда используется один раз для всего массива, но вы используете его повторно для каждой строки. Выполнение чего-либо по строкам происходит медленно pandas . И в рамках where того, что вы делаете df['id']==row['id'] (и для «года»), проверяя значение строки по всему столбцу. Я не вижу цели этого теста в (многословном) описании.

3. @hpaulj Действительно. Даже с многословными описаниями есть люди, которые просто не могут этого понять