Question: I have one pandas dataframe and one geopandas dataframe. In the Pandas dataframe, I have a column *Points* that contains `shapely.geometry` `Point` objects. The *geometry* column in the geopandas frame has `Polygon` objects. What I would like to do is take a `Point` in the Pandas frame and test to see if it is `within` **any** of the `Polygon` objects in the geopandas frame.

In a new column in the pandas frame, I would like the following. If the `Point` is within a given `Polygon` (i.e. `within` call returns `True`), I would like the new column's value at the `Point`'s row to be the value of a different column in the `Polygon`'s row in the geopandas frame.

I have a working solution to this problem, but it is not vectorized. Is it possible to vectorize it?

Example:

```py
import geopandas as gpd
import pandas as pd
from shapely.geometry import Point, Polygon

# Create random frame, geometries are supposed to be mutually exclusive
gdf = gpd.GeoDataFrame({'A': [1, 2], 'geometry': [Polygon([(10, 5), (5, 6)]), Polygon([(1,2), (2, 5))]})

# Create random pandas
df = pd.DataFrame({'Foo': ['bar', 'Bar'], 'Points': [Point(4, 5), Point(1, 2)]})

# My non-vectorized solution
df['new'] = ''
for i in df.index:
    for j in gdf.index:
        if df.at[i, 'Points'].within(gdf.at[j, 'geometry']):
            df.at[i, 'new'] = gdf.at[j, 'A'] 

```

This works fine, so that `df['new']` will contain whatever is in column `gdf['A']` when the point is within the polygon. I am hoping that there may be a way for me to vectorize this operation.

Answer: 
You can calculate the Euclidean distance between all the points of the `Points` and `Polygon`. And, wherever the distance is equal to 0, this would give you an intersection point. My approach is below. Note that, I leave the part of getting all the points and the polygon points from your data frames to you. Probably, a function like `pandas.Series.toList` should provide that.

```
import numpy as np
from scipy.spatial.distance import cdist

polygon = [[10,5],[5,6],[1,2],[2,5]]
points = [[4,5],[1,2]]

# return distances between all the items of the two arrays
distances = cdist(polygon,points) 

print(distances)

```

```
[[6.         9.48683298]
 [1.41421356 5.65685425]
 [4.24264069 0.        ]
 [2.         3.16227766]]

```

All we have to do now, is to get the index of 0s in the array. As you can see, our intersection point is at the 3rd row and the 2nd column, which is the 3rd item of the polygon or the 2nd item of the points.

```

for i,dist in enumerate(distances.flatten()):
    if dist==0:
        intersect_index = np.unravel_index(i,shape=distances.shape)
        intersect_point = polygon[intersect_index[0]]
        print(intersect_point)

```

```
[1,2]

```

This should give you the vectorized form you are looking for.
I found a solution that works for my purposes. Not the most elegant, but still much faster than looping.

```py
def within_vectorized(array, point):
# Create array of False and True values 
    _array = np.array([point.within(p) for p in array])
# When the first element of np.where tuple is not empty
    if np.where(_array)[0].size != 0:
        return np.where(_array)[0][0]
    else:
        return -1

# Create dummy value row geopandas frame
# This will have an empty Polygon object in the geometry column and NaN's everywhere else
dummy_values = np.empty((1, gdf.shape[1]))
dummy_values[:] = np.nan
dummy_values = dummy_values.tolist()[0]
dummy_values[-1] = Polygon()
gdf.loc[-1] = dummy_values

# Use loc where index is retrieved by calling vectorized function
df['A'] = gdf.loc[df['Point'].apply(lambda x: within_vectorized(gdf['geometry'], x)), 'A'].to_list()

```