Lists / DataFrames - запуск функции над всеми значениями в Python - PullRequest
1 голос
/ 03 марта 2020

Я застрял на данный момент и не знаю, как решить эту проблему. Я хочу применить этот расчет к списку / фрейму данных:

Distance interpolation - inverse distance weighted

Само уравнение на самом деле не проблема для меня, я могу легко решить это вручную, но это не относится к количеству данных, которые у меня есть.

  • v: приближаемое значение
  • vi: известные значения (в моем случае температура)
  • di: расстояние до аппроксимируемой точки

Таким образом, в основном это для вычисления / аппроксимации нового значения температуры для позиции на определенном расстоянии от углов квадрата:

enter image description here

import pandas as pd
import numpy as np
import xarray as xr
import math

filepath = r'F:\Data\data.nc' # just the path to the file
obj= xr.open_dataset(filepath)
# This is where I get the coordinates for each of the corners of the square
# from the netcdf4 file

lat = 9.7398
lon = 51.2695
xlat = obj['XLAT'].values
xlon = obj['XLON'].values           
p_1 = [xlat[0,0], xlon[0,0]]
p_2 = [xlat[0,1], xlon[0,1]]
p_3 = [xlat[1,0], xlon[1,0]]
p_4 = [xlat[1,1], xlon[1,1]]

p_rect = [p_1, p_2, p_3, p_4]
p_orig = [lat, lon]

#=================================================
# Calculates the distance between the points
# d = sqrt((x2-x1)^2 + (y2-y1)^2))
#=================================================   
distance = []
for coord in p_rect:
    distance.append(math.sqrt(math.pow(coord[0]-p_orig[0],2)+math.pow(coord[1]-p_orig[1],2)))

# to get the values for they key['WS'] for example:
a = obj['WS'].values[:,0,0,0] # Array of floats for the first values
b = obj['WS'].values[:,0,0,1] # Array of floats for the second values
c = obj['WS'].values[:,0,1,0] # Array of floats for the third values
d = obj['WS'].values[:,0,1,1] # Array of floats for the fourth values

С тех пор я понятия не имею, как мне следует продолжать, если я должен делать:

df = pd.DataFrame()
df['a'] = a
df['b'] = b
df['c'] = c
df['d'] = d

Тогда как-то работать с DataFrames и сбросьте abcd после того, как я получу необходимые значения или я должен сначала сделать это со списками, а затем добавить только результат в dataframe. Я немного растерялся.

Единственное, что я придумал, так это то, как бы я выглядел, если бы я делал это вручную:

for i starting at 0 and ending if the end of the list [a, b, c d have the same length] is reached .

     1/a[i]^2*distance[0] + 1/b[i]^2*distance[1] + 1/c[i]^2*distance[2] + 1/d[i]^2*distance[3]
v =  ------------------------------------------------------------------------------------------
                    1/a[i]^2 + 1/b[i]^2 + 1/c[i]^2 + 1/d[i]^2
'''  

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

PS: вот ссылка на файл: ССЫЛКА НА ФАЙЛ

1 Ответ

1 голос
/ 03 марта 2020

Просто векторизовать ваши расчеты. С фреймами данных вы можете выполнять целые арифметические операции c непосредственно над столбцами, как если бы они были скалярами для генерации другого столбца, df['v']. Ниже предполагается, что distance - это список из четырех скаляров, и помните, что Python ^ не означает мощность, вместо этого используется **.

df = pd.DataFrame({'a':a, 'b':b, 'c':c, 'd':d})

df['v'] = (1/df['a']**2 * distance[0] +
           1/df['b']**2 * distance[1] + 
           1/df['c']**2 * distance[2] + 
           1/df['d']**2 * distance[3]) / (1/df['a']**2 + 
                                          1/df['b']**2 + 
                                          1/df['c']**2 + 
                                          1/df['d']**2)

Или функциональная форма, использующая Pandas Series бинарные операторы . Ниже следует порядок операций (круглые скобки -> экспоненциальная -> умножение / деление -> сложение / вычитание):

df['v'] = (df['a'].pow(2).pow(-1).mul(distance[0]) +
           df['b'].pow(2).pow(-1).mul(distance[1]) + 
           df['c'].pow(2).pow(-1).mul(distance[2]) + 
           df['d'].pow(2).pow(-1).mul(distance[3])) / (df['a'].pow(2).pow(-1) + 
                                                       df['b'].pow(2).pow(-1) + 
                                                       df['c'].pow(2).pow(-1) + 
                                                       df['d'].pow(2).pow(-1))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...