1

I'd like to perform a calculation over an X, Y data to produce a calculated Z. My code is below:

Example Data set for injection_wells.csv

Name X Y Q
MW-1 2517700 996400 5
MW-2 2517770 996420 5
import pandas as pd
import math
import numpy as np
import matplotlib.mlab as mlab
import matplotlib.tri as tri

IW = pd.read_csv (r'Injection_wells.csv')

`Note that - Injection wells is a table of three wells with names, X, Y, and Q (flow rate).`

#pull all the relevant well information by well into their own arrays

MW1 = IW[IW['Name'] == 'MW1']
MW2 = IW[IW['Name'] == 'MW2']
MW3 = IW[IW['Name'] == 'MW3']

#initiate grid
xi = np.linspace(2517675,2517800,625)
yi = np.linspace(996300,996375,375)

#make it so i can apply np.float to an array
vector = np.vectorize(np.float)

X,Y = np.meshgrid(xi,yi)

#perform calculation over every X and Y.
PSI = ((MW1['Q']/(2*math.pi))*(np.arctan(((vector(X[None,:]))-np.float(MW1['X']))/(vector(Y[:,None])-np.float(MW1['Y']))))+
      (MW2['Q']/(2*math.pi))*(np.arctan(((vector(X[None,:])-np.float(MW2['X']))/vector((Y[:,None])-np.float(MW2['Y'])))))+
      (MW3['Q']/(2*math.pi))*(np.arctan(((vector((X[None,:])-np.float(MW3['X']))/vector((Y[:,None])-np.float(MW3['Y'])))))))

I get the error:

ValueError                                Traceback (most recent call last)
<ipython-input-11-fd6ee058014f> in <module>
     17 X,Y = np.meshgrid(xi,yi)
     18 
---> 19 PSI = ((MW1['Q']/(2*math.pi))*(np.arctan(((vector(X[None,:]))-np.float(MW1['X']))/(vector(Y[:,None])-np.float(MW1['Y']))))+
     20       (MW2['Q']/(2*math.pi))*(np.arctan(((vector(X[None,:])-np.float(MW2['X']))/vector((Y[:,None])-np.float(MW2['Y'])))))+
     21       (MW3['Q']/(2*math.pi))*(np.arctan(((vector((X[None,:])-np.float(MW3['X']))/vector((Y[:,None])-np.float(MW3['Y'])))))))

~\Anaconda3\lib\site-packages\pandas\core\ops\common.py in new_method(self, other)
     63         other = item_from_zerodim(other)
     64 
---> 65         return method(self, other)
     66 
     67     return new_method

~\Anaconda3\lib\site-packages\pandas\core\ops\__init__.py in wrapper(left, right)
    343         result = arithmetic_op(lvalues, rvalues, op)
    344 
--> 345         return left._construct_result(result, name=res_name)
    346 
    347     wrapper.__name__ = op_name

~\Anaconda3\lib\site-packages\pandas\core\series.py in _construct_result(self, result, name)
   2755         # We do not pass dtype to ensure that the Series constructor
   2756         #  does inference in the case where `result` has object-dtype.
-> 2757         out = self._constructor(result, index=self.index)
   2758         out = out.__finalize__(self)
   2759 

~\Anaconda3\lib\site-packages\pandas\core\series.py in __init__(self, data, index, dtype, name, copy, fastpath)
    311                 try:
    312                     if len(index) != len(data):
--> 313                         raise ValueError(
    314                             f"Length of passed values is {len(data)}, "
    315                             f"index implies {len(index)}."

ValueError: Length of passed values is 375, index implies 1.

I know that this has something to do with me trying to apply a function to an array that only accepts one value. I am trying to overcome this issue and be able to perform this calculation as is on the entire gridded data set. Any help on this would be greatly appreciated.

The equation i'm trying to do is below. Note that the theta in the equation is the arc tan of distance from the grid node to the injection well (for each grid node) which is what i'm trying to replicate in the code.

Equation for the code below

Thanks

Melanie
  • 109
  • 1
  • 9
  • Couple questions: why do you need to apply `np.float` to an array? Are your arrays not already numeric? I'd suggest using [`np.astype`](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.astype.html), as `np.vectorize` doesn't do anything (it's just a `for` loop). Second, I suggest implementing a named function `f(x, y) -> z` to which you can pass `X[None, :]` and `Y[:, None]` as arguments, to help simplify and clarify the function being evaluated. – ddejohn Oct 21 '21 at 21:18
  • Can you provide some a small sample of your data, and your expected output? – ddejohn Oct 21 '21 at 21:18
  • 1
    `X[None,:]` produces a three dimensional array (shape = (1,375,625)). Were you trying to extract just one dimension? Like `X[0,:]`? – Tim Roberts Oct 21 '21 at 21:21
  • Breakup the long expression to better identify where the error occurs. And show the full error. You/we need to know exactly which action is causing the problem. No guessing allowed! – hpaulj Oct 21 '21 at 21:22
  • @ddejohn the np.float was me desperately trying to overcome issues with np.arctan. I read that it only accepts floats and I assumed that my grid was integers. I will post an edit with example data. – Melanie Oct 21 '21 at 21:22
  • I also wanted to ask what the intention was with adding axes. – ddejohn Oct 21 '21 at 21:22
  • You've got three different parenthesizations in your function and it's hard to tell what exactly you're trying to do, or if they should all be the same. Any possibility you could share the symbolic equation? It looks like you're trying to do two different things here: evaluating a function `f(x, y)` over a meshgrid, and *also* evaluating `f(x, y)` at specific values of `x` and `y`? – ddejohn Oct 21 '21 at 21:31
  • @ddjohn I will add the equation to the post. I added axes to be able to see if the grid was being properly produced. – Melanie Oct 21 '21 at 21:35
  • @TimRoberts using X[None,:] I was trying to pull all x values in the array so the calculation was made for each x value. I didn't realize it produces a 3d array? – Melanie Oct 21 '21 at 21:52
  • Wait, your function does *not* look like a simple `f(x, y)`... Can you clarify what Q2 and Q3 are? Do you mean that those are the Q values from rows 2 and 3? – ddejohn Oct 21 '21 at 21:54
  • @ddejohn I've added the equation. – Melanie Oct 21 '21 at 21:55
  • And @hpaulj i will work on breaking it up and see if i can identify the exact issue. I will post the entire error. – Melanie Oct 21 '21 at 21:55

1 Answers1

0

I'm gonna jump the gun here as I think I understand the problem now, after looking at it a bit more.

So you've got a DataFrame of injection well data, with four columns:

name    x    y    q
str   int  int  int

And you have a function f(x, y, q) -> z that you want to evaluate. I'm not sure I follow exactly what your function is doing because it's formatted in such a way that it's pretty hard to read, so I'll use a simplified example:

def func(x, y, q):
    return (q / 2 * np.pi) * np.arctan(y, x)

Now instead of breaking your well data into different arrays, simply apply the function over the entire dataframe row-wise:

df["z"] = func(df.x, df.y, df.q)
ddejohn
  • 8,775
  • 3
  • 17
  • 30
  • This worked! The only thing i had to change was I needed to perform the calculation over an entire grid I initialized rather than the data frame. However applying the same logic above got the desired result. Thank you! – Melanie Oct 22 '21 at 00:49