当我运行以下函数时,我只得到一个值的输出。 有消息, “条件长度> 1,只使用第一个元素”
我需要做些什么更改才能获得所有值?
ownsquare <- function(n)
{
for (i in seq(from = 1, to = 506, by = 0.001))
{
r <- i * i
if (r <= n) x=i
}
x
}
答案 0 :(得分:1)
您正在尝试创建一个可以对多个值执行相同操作的函数,返回与其参数长度相等的向量。在R的说法中,函数的行为被称为“向量化”。并且mapply
函数周围有一个名为Vectorize
的包装函数。这说明它与您的函数一起使用,它可以在单个元素上正常工作:
Vownsquare <- Vectorize(ownsquare)
Vownsquare( 1:10 )
#-------
[1] 1.000 1.414 1.732 2.000 2.236 2.449 2.645 2.828 3.000 3.162
这真的很慢,但这是实施效率低下的结果。学习使用break
可能会提高效率。这避免了在达到条件r> n之后的不必要的迭代。
ownsquare <- function(n)
{
for (i in seq(from = 1, to = 506, by = 0.001))
{
r <- i * i
if (r > n) { x=i; break() }
}
x
}
Vownsquare <- Vectorize(ownsquare)
Vownsquare( 1:10 )
[1] 1.001 1.415 1.733 2.001 2.237 2.450 2.646 2.829 3.001 3.163
请注意Lundberg实现的比较,该实现计算每个参数的完整506,000长度向量:
system.time(ownsquare2(1:10)) # makes full vectors
user system elapsed
7.311 0.069 7.292
system.time(ownsquare(1:10)) # uses break
user system elapsed
0.008 0.000 0.008
system.time(Vownsquareoriginal( 1:10 )) # full vectors with if()
user system elapsed
3.746 0.040 3.729
答案 1 :(得分:1)
向量化此函数的另一种方法是使用import netCDF4 as nc
import pandas as pd
import numpy as np
import datetime as datetime
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
## Read in netCDF file. NOTE: Change format if it does not read.
NH_Ice=nc.Dataset('Oc-Tech/Final_Project/ncFiles/NH_SeaIce.nc', 'r')
## Save netCDF parameters into arrays.
lons = NH_Ice.variables['longitude'][:]
lats = NH_Ice.variables['latitude'][:]
time = NH_Ice.variables['time'][:]
time_units = NH_Ice.variables['time'].units
## Calculate Date from given data file
dbase= '2001-01-01 00:00:00'
db=datetime.datetime.strptime(dbase, "%Y-%m-%d %H:%M:%S")
start=db+datetime.timedelta(days=time[0])
end=db+datetime.timedelta(days=time[-1])
#print fh.time_strlen
si = NH_Ice.variables['seaice_conc'][:]
NH_Ice.close()
m = Basemap(projection='npstere',boundinglat=45,lon_0=-156,resolution='c')
#total time steps
tts=1980
for ti in range(0,tts):
fig = None
lat = None
lon = None
xi = None
yi = None
sip = None
fig=plt.figure(figsize=(10,10))
m.drawcoastlines(color='black')
m.fillcontinents(color='limegreen',lake_color='blue')
m.drawparallels(np.arange(-80.,81.,20.))
m.drawmeridians(np.arange(-180.,181.,20.))
m.drawmapboundary(fill_color='darkblue')
lon, lat = np.meshgrid(lons, lats) #sea ice
xi, yi = m(lon, lat)
sip=(si[ti]) ## Plot u data from a particular day
m.pcolor(xi,yi,np.squeeze(sip))
plt.savefig("fig"+str(ti)+".png")
#plt.close(fig)
而不是ifelse
:
if
此处,ownsquare2 <- function(n)
{
for (i in seq(from = 1, to = 506, by = 0.001))
{
r <- i * i
x <- ifelse(r <= n, i, x)
}
x
}
ownsquare2(1:10)
## [1] 1.000 1.414 1.732 2.000 2.236 2.449 2.645 2.828 3.000 3.162
被视为函数中的向量,x
表达式中使用的替换使用if
进行矢量化。
从ifelse
到if
的转换相当简单,但对于链接的if-else代码变得不可读(IMO)。