我有一个包含点的geopandas数据框
df:
geometry
0 POINT (806470.3646198167 2064879.919354021)
1 POINT (792603.391127742 2170760.8355139)
2 POINT (787263.3037740411 2050925.953643546)
3 POINT (809203.6762813283 2160874.194588484)
4 POINT (781668.2687635225 2051524.634389534)
对于每个要应用此功能的点:
def returnValuePoints(df, i):
points_list = [ (df['geometry'][i].x, df['geometry'][i].y) ] #list of X,Y coordinates
for point in points_list:
col = int((point[0] - xOrigin) / pixelWidth)
row = int((yOrigin - point[1] ) / pixelHeight)
return (row, col)
这就是我在做什么:
for i in df.index:
val = returnValuePoints(df, data, i)
如何避免循环,并使用apply()
将此功能应用于所有行
答案 0 :(得分:1)
关于以下代码的警告:由于无法访问geopandas环境,因此我尚未进行实际测试。但是,我认为它应该可以工作。
我认为您实际上不想在这里使用申请。使用geopandas方法,可以通过应用一些仿射变换来获得点的geopandas GeoSeries
:
首先,您用translate
xOrigin, yOrigin
点系列:
translated = df['geometry'].translate(xoff=-1*xOrigin, yoff=-1*yOrigin)
然后,您既可以围绕x轴进行反射,也可以使用pixelWidth, pixelHeight
通过scale
进行缩放:
scaled_translated = translated.scale(xfact=1/pixelWidth, yfact=-1/pixelHeight)
在此处乘以-1即可进行反射。相反,如果您打算做(point[1] - yOrigin)
,则可以用1代替-1。
这将给您GeoSeries
。如果需要一系列 integer 点对,则必须做更多的工作。下面的代码将为您提供两个分别带有x和y值的整数Series
(要求geopandas版本> 0.3.0):
x_val = scaled_translated.x.astype(int)
y_val = scaled_translated.y.astype(int)
然后,您可以将其放入原始数据框中:
df['x_val'] = x_val
df['y_val'] = y_val
如果您真的想要一个元组列表(我想您可能不应该!您失去了熊猫的所有优势!),您可以这样做:
list(df[['x_val', 'y_val']].itertuples(index=False, name=None))
答案 1 :(得分:0)
首先,您需要重组您的方法,以便它采用可在apply中使用lambda函数传递的值(考虑如何对单个行的值进行操作):
def returnValuePoints(x, y):
point = (x, y)
col = int((point[0] - xOrigin) / pixelWidth)
row = int((yOrigin - point[1] ) / pixelHeight)
return (row, col)
第二,您可以使用axis = 1调用数据框上的Apply,以便能够访问每一行的列值:
val = df.apply(lambda x: returnValuePoints(x.geometry.x, x.geometry.y), axis=1)
答案 2 :(得分:0)
我将向您展示一个示例。
import pandas as pd
# reading csv
s = pd.read_csv("stock.csv", squeeze = True)
# defining function to check price
def fun(num):
if num<200:
return "Low"
elif num>= 200 and num<400:
return "Normal"
else:
return "High"
# passing function to apply and storing returned series in new
new = s.apply(fun)
# printing first 3 element
print(new.head(3))
# printing elements somewhere near the middle of series
print(new[1400], new[1500], new[1600])
# printing last 3 elements
print(new.tail(3))