Turn a 1D array into a sample by OpenTURNS in Python

609 Views Asked by At

I'm trying to interpolate responses on a 2D grid by Kriging following this example: How to interpolate 2D spatial data with kriging in Python?

However, when I'm trying to create a sample from 1D array in OpenTURNS,

import numpy as np
import openturns as ot
observations = ot.Sample(np.array([1,2,3]))

I keep getting this error

TypeError: Wrong number or type of arguments for overloaded function 'new_Sample'.
  Possible C/C++ prototypes are:
    OT::Sample::Sample()
    OT::Sample::Sample(OT::UnsignedInteger const,OT::UnsignedInteger const)
    OT::Sample::Sample(OT::UnsignedInteger const,OT::Point const &)
    OT::Sample::Sample(OT::Sample const &,OT::UnsignedInteger const,OT::UnsignedInteger const)
    OT::Sample::Sample(OT::SampleImplementation const &)
    OT::Sample::Sample(OT::Sample const &)
    OT::Sample::Sample(PyObject *)

This doesn't do the job either:

observations = ot.Sample(np.array([[1],[2],[3]]))
1

There are 1 best solutions below

0
On

The exception is because this is an ambiguous situation. The array contains 3 values: the Sample class does not know if this data corresponds to a sample made of 3 points in dimension 1, or a sample with one point in dimension 3.

The classes which clarify this are:

  • the ot.Point() class manages a multidimensional real vector - it has a dimension (the number of components),
  • the ot.Sample() manages collection of points - it has a size (the number of points in the sample) and a dimension (the dimension of each point in the sample).

There are automatic conversions between Python data types and OpenTURNS data types:

  • a Python list or tuple or a 1D numpy array is automatically converted to a ot.Point()
  • a Python list of lists or a 2D numpy array is automatically converted to a ot.Sample()

A common way to create a 1-dimension Sample is from a list of floating point numbers. Please let me illustrate these three constructions.

(Case 1) To create a Point from a 1D array, we just pass it to the Point class:

import numpy as np
import openturns as ot

array_1D = np.array([1.0, 2.0, 3.0])
point = ot.Point(array_1D)
print(point)

This prints [1,2,3], i.e. a point in dimension 3.

(Case 2) To create a Sample from a 2D array, we add the required square brackets.

array_2D = np.array([[1.0], [2.0], [3.0]])
sample = ot.Sample(array_2D)
print(sample)

This prints:

0 : [ 1 ]
1 : [ 2 ]
2 : [ 3 ]

This is a sample made of 3 points ; each point has one dimension.

(Case 3) We often have to create a Sample from a list of floats. This can be done more easily with a list comprehension.

list_of_floats = [1.0, 2.0, 3.0]
sample = ot.Sample([[v] for v in list_of_floats])
print(sample)

This prints the same sample as in the previous example. The last script:

observations = ot.Sample(np.array([[1],[2],[3]]))  
# Oups: should use 1.0 instead of 1

works fine on my machine. Please be aware that OpenTURNS only manages points of floating point values, but not of int types. This is why I write:

observations = ot.Sample(np.array([[1.0], [2.0], [3.0]]))  

to make this clear enough. The call to the array function is, however, unnecessary. It is simpler to use:

observations = ot.Sample([[1.0], [2.0], [3.0]])