本文的目的是介绍NumPy或Pandas:将数组类型保持为整数,同时具有NaN值的详细情况,特别关注怎么把numpy数组里的数都改成int型的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,
本文的目的是介绍NumPy 或 Pandas:将数组类型保持为整数,同时具有 NaN 值的详细情况,特别关注怎么把numpy数组里的数都改成int型的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解NumPy 或 Pandas:将数组类型保持为整数,同时具有 NaN 值的机会,同时也不会遗漏关于"CALayer position contains NaN: [nan nan]" 自定义滑块导致的错误信息、/opt/conda/lib/python3.6/site-packages/pandas/core/ops.py:816: pandas 处理 NaN、JavaScript Puzzlers! 解惑(一):为什么 ["1", "2", "3"].map(parseInt) 返回 [1,NaN,NaN]?、numpy.random.random & numpy.ndarray.astype & numpy.arange的知识。
本文目录一览:- NumPy 或 Pandas:将数组类型保持为整数,同时具有 NaN 值(怎么把numpy数组里的数都改成int型)
- "CALayer position contains NaN: [nan nan]" 自定义滑块导致的错误信息
- /opt/conda/lib/python3.6/site-packages/pandas/core/ops.py:816: pandas 处理 NaN
- JavaScript Puzzlers! 解惑(一):为什么 ["1", "2", "3"].map(parseInt) 返回 [1,NaN,NaN]?
- numpy.random.random & numpy.ndarray.astype & numpy.arange
NumPy 或 Pandas:将数组类型保持为整数,同时具有 NaN 值(怎么把numpy数组里的数都改成int型)
是否有一种首选方法可以将numpy
数组的数据类型固定为int
(int64
或其他),同时仍将内部元素列为numpy.NaN
?
特别是,我正在将内部数据结构转换为 Pandas DataFrame。在我们的结构中,我们有仍然有 NaN 的整数类型列(但列的 dtype 是
int)。如果我们将其设为 DataFrame,似乎会将所有内容重铸为浮点数,但我们真的很想成为int
.
想法?
尝试的事情:
我尝试使用from_records()
pandas.DataFrame 下的函数,coerce_float=False
但这并没有帮助。我还尝试使用
NumPy 掩码数组和 NaN fill_value,这也不起作用。所有这些都导致列数据类型变为浮点数。
"CALayer position contains NaN: [nan nan]" 自定义滑块导致的错误信息
如何解决"CALayer position contains NaN: [nan nan]" 自定义滑块导致的错误信息
我有一个视频播放器开始播放视频(来自 firebase URL),在某些情况下(70% 的情况)我在物理设备上运行时收到此错误消息(异常)(但在模拟器中启动时没有问题) : “CALayer 位置包含 NaN:[nan nan]”
我发现当我评论“VideoPlayerControlsView()”时没有出现错误,所以我很确定问题是我的 CustomerSlider 对象位于这个 VideoPlayerControlsView 视图的内部。
我认为这可能是由加载远程视频引起的,因为视频没有加载,应用程序不知道 AVPlayer 对象的大小/边界,因此无法创建一些父视图(可能是 CustomerSlider)。 .
构建一个最小的可重现示例将是一场噩梦,我只是希望有些人能在我的代码/逻辑中发现错误..如果没有 - 当然会构建它。别无选择。
struct DetailedplayerView : View {
// The progress through the video,as a percentage (from 0 to 1)
@State private var videoPos: Double = 0
// The duration of the video in seconds
@State private var videoDuration: Double = 0
// Whether we''re currently interacting with the seek bar or doing a seek
@State private var seeking = false
private var player: AVPlayer = AVPlayer()
init(item: ExerciseItem,hVideoURL: URL?) {
if hVideoURL != nil {
player = AVPlayer(url: hVideoURL!)
player.isMuted = true
player.play()
} else {
print("[debug] hVideoURL is nil")
}
}
var body: some View {
ZStack {
//vstack {
VideoPlayerView(videoPos: $videoPos,videoDuration: $videoDuration,seeking: $seeking,//timeline: $timeline,//videoTimeline: videoTimeline,player: player)
.frame(width: UIScreen.screenHeight,height: UIScreen.screenWidth)
vstack {
Spacer()
VideoPlayerControlsView(videoPos: $videoPos,**<<-----------------------**
videoDuration: $videoDuration,player: player)
.frame(width: UIScreen.screenHeight - 2*Constants.scrollPadding,height: 20)
.padding(.bottom,20)
}
}
.ondisappear {
// When this View isn''t being shown anymore stop the player
self.player.replaceCurrentItem(with: nil)
}
}
}
struct VideoPlayerControlsView : View {
@Binding private(set) var videoPos: Double
@Binding private(set) var videoDuration: Double
@Binding private(set) var seeking: Bool
// @Binding private(set) var timeline: [Advice]
@State var shouldStopPlayer: Bool = false
@State var player: AVPlayer
//let player: AVPlayer
@State private var playerPaused = false
var body: some View {
HStack {
// Play/pause button
Button(action: togglePlayPause) {
Image(systemName: playerPaused ? "arrowtriangle.right.fill" : "pause.fill")
.foregroundColor(Color.mainSubtitleColor)
.contentShape(Rectangle())
.padding(.trailing,10)
}
// Current video time
if videoPos.isFinite && videoPos.isCanonical && videoDuration.isFinite && videoDuration.isCanonical {
Text(Utility.formatSecondsToHMS(videoPos * videoDuration))
.foregroundColor(Color.mainSubtitleColor)
}
// Slider for seeking / showing video progress
CustomSlider(value: $videoPos,shouldStopPlayer: self.$shouldStopPlayer,range: (0,1),knobWidth: 4) { modifiers in
ZStack {
Group {
Color(#colorLiteral(red: 1,green: 1,blue: 1,alpha: 0.5799999833106995))//Color((red: 0.4,green: 0.3,blue: 1)
.opacity(0.4)
.frame(height: 4)
.modifier(modifiers.barRight)
Color.mainSubtitleColor//Color(red: 0.4,blue: 1)
.frame(height: 4)
.modifier(modifiers.barLeft)
}
.cornerRadius(5)
vstack {
Image(systemName: "arrowtriangle.down.fill") // SF Symbol
.foregroundColor(Color.mainSubtitleColor)
.offset(y: -3)
}
.frame(width: 20,height: 20)
.contentShape(Rectangle())
.modifier(modifiers.knob)
}
}
.onChange(of: shouldStopPlayer) { _ in
if shouldStopPlayer == false {
print("[debug] shouldStopPlayer == false")
sliderEditingChanged(editingStarted: false)
} else {
if seeking == false {
print("[debug] shouldStopPlayer == true")
sliderEditingChanged(editingStarted: true)
}
}
}
.frame(height: 20)
// Video duration
if videoDuration.isCanonical && videoDuration.isFinite {
Text(Utility.formatSecondsToHMS(videoDuration))
.foregroundColor(Color.mainSubtitleColor)
}
}
.padding(.leading,40)
.padding(.trailing,40)
}
private func togglePlayPause() {
pausePlayer(!playerPaused)
}
private func pausePlayer(_ pause: Bool) {
playerPaused = pause
if playerPaused {
player.pause()
}
else {
player.play()
}
}
private func sliderEditingChanged(editingStarted: Bool) {
if editingStarted {
// Set a flag stating that we''re seeking so the slider doesn''t
// get updated by the periodic time observer on the player
seeking = true
pausePlayer(true)
}
// Do the seek if we''re finished
if !editingStarted {
let targetTime = CMTime(seconds: videoPos * videoDuration,preferredTimescale: 600)
player.seek(to: targetTime) { _ in
// Now the seek is finished,resume normal operation
self.seeking = false
self.pausePlayer(false)
}
}
}
}
extension Double {
func convert(fromrange: (Double,Double),toRange: (Double,Double)) -> Double {
// Example: if self = 1,fromrange = (0,2),toRange = (10,12) -> solution = 11
var value = self
value -= fromrange.0
value /= Double(fromrange.1 - fromrange.0)
value *= toRange.1 - toRange.0
value += toRange.0
return value
}
}
struct CustomSliderComponents {
let barLeft: CustomSliderModifier
let barRight: CustomSliderModifier
let knob: CustomSliderModifier
}
struct CustomSliderModifier: ViewModifier {
enum Name {
case barLeft
case barRight
case knob
}
let name: Name
let size: CGSize
let offset: CGFloat
func body(content: Content) -> some View {
content
.frame(width: (size.width >= 0) ? size.width : 0)
.position(x: size.width*0.5,y: size.height*0.5)
.offset(x: offset)
}
}
struct CustomSlider<Component: View>: View {
@Binding var value: Double
var range: (Double,Double)
var knobWidth: CGFloat?
let viewbuilder: (CustomSliderComponents) -> Component
@Binding var shouldStopPlayer: Bool
init(value: Binding<Double>,shouldStopPlayer: Binding<Bool>,range: (Double,knobWidth: CGFloat? = nil,_ viewbuilder: @escaping (CustomSliderComponents) -> Component
) {
_value = value
_shouldStopPlayer = shouldStopPlayer
self.range = range
self.viewbuilder = viewbuilder
self.knobWidth = knobWidth
}
var body: some View {
return GeometryReader { geometry in
self.view(geometry: geometry) // function below
}
}
private func view(geometry: GeometryProxy) -> some View {
let frame = geometry.frame(in: .global)
let drag = DragGesture(minimumdistance: 0)
.onChanged { drag in
shouldStopPlayer = true
self.onDragChange(drag,frame)
}
.onEnded { drag in
shouldStopPlayer = false
//self.updatedValue = value
print("[debug] slider drag gesture ended,value = \\(value)")
}
let offsetX = self.getoffsetX(frame: frame)
let knobSize = CGSize(width: knobWidth ?? frame.height,height: frame.height)
let barLeftSize = CGSize(width: CGFloat(offsetX + knobSize.width * 0.5),height: frame.height)
let barRightSize = CGSize(width: frame.width - barLeftSize.width,height: frame.height)
let modifiers = CustomSliderComponents(
barLeft: CustomSliderModifier(name: .barLeft,size: barLeftSize,offset: 0),barRight: CustomSliderModifier(name: .barRight,size: barRightSize,offset: barLeftSize.width),knob: CustomSliderModifier(name: .knob,size: knobSize,offset: offsetX))
return ZStack { viewbuilder(modifiers).gesture(drag) }
}
private func onDragChange(_ drag: DragGesture.Value,_ frame: CGRect) {
let width = (knob: Double(knobWidth ?? frame.size.height),view: Double(frame.size.width))
let xrange = (min: Double(0),max: Double(width.view - width.knob))
var value = Double(drag.startLocation.x + drag.translation.width) // knob center x
value -= 0.5*width.knob // offset from center to leading edge of knob
value = value > xrange.max ? xrange.max : value // limit to leading edge
value = value < xrange.min ? xrange.min : value // limit to trailing edge
value = value.convert(fromrange: (xrange.min,xrange.max),toRange: range)
//print("[debug] slider drag gesture detected,value = \\(value)")
self.value = value
}
private func getoffsetX(frame: CGRect) -> CGFloat {
let width = (knob: knobWidth ?? frame.size.height,view: frame.size.width)
let xrange: (Double,Double) = (0,Double(width.view - width.knob))
let result = self.value.convert(fromrange: range,toRange: xrange)
return CGFloat(result)
}
}
一些额外的代码展示了如何触发DetailedplayerView:
struct DetailedVideo: View {
var item: ExerciseItem
var url: URL
@Binding var isPaused: Bool
var body: some View {
ZStack {
DetailedplayerView(item: self.item,hVideoURL: url)
//.frame(width: 500,height: 500) //@@UPDATED: Apr 10
HStack {
vstack {
ZStack {
//Rectangle 126
RoundedRectangle(cornerRadius: 1)
.fill(Color(#colorLiteral(red: 0.3063802123069763,green: 0.3063802123069763,blue: 0.3063802123069763,alpha: 1)))
.frame(width: 2,height: 20.3)
.rotationEffect(.degrees(-135))
//Rectangle 125
RoundedRectangle(cornerRadius: 1)
.fill(Color(#colorLiteral(red: 0.3063802123069763,height: 20.3)
.rotationEffect(.degrees(-45))
}
.frame(width: 35,height: 35)//14.4
.contentShape(Rectangle())
.onTapGesture {
print("[debugUI] isPaused = false")
self.isPaused = false
}
.offset(x:20,y:20)
Spacer()
}
Spacer()
}
}
.ignoresSafeArea(.all)
}
}
@viewbuilder
var detailedVideoView: some View {
if self.hVideoURL != nil {
DetailedVideo(item: self.exerciseVM.exerciseItems[self.exerciseVM.currentIndex],url: self.hVideoURL!,isPaused: self.$exerciseVM.isPaused) // when is paused - we are playing detailed video?
.frame(width: UIScreen.screenHeight,height: UIScreen.screenWidth) //UPDATED: Apr 9,2021
.onAppear {
AppDelegate.orientationLock = UIInterfaceOrientationMask.landscapeLeft
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue,forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
}
.ondisappear {
dispatchQueue.main.async {
AppDelegate.orientationLock = UIInterfaceOrientationMask.portrait
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue,forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
}
}
} else {
EmptyView()
}
}
/opt/conda/lib/python3.6/site-packages/pandas/core/ops.py:816: pandas 处理 NaN
这里记录一下犯过的及其傻帽的错误!!!!哈哈,无语,同时讨论一下NaN这个数据类型的处理
/opt/conda/lib/python3.6/site-packages/pandas/core/ops.py:816: FutureWarning: elementwise comparison Failed; returning scalar instead,but in the future will perform elementwise comparison result = getattr(x,name)(y)
....................
TypeError: invalid type comparison
这里有一个优惠券的scv表:
import numpy as np
import pandas as pd
dfoff = pd.read_csv("datalab/4901/ccf_offline_stage1_train.csv")
dfofftest = pd.read_csv("datalab/4901/ccf_offline_stage1_test_revised.csv")
dfoff.head()
笔者这里的目的是想统计出 Coupon_id是非NaN(非空)且Date是NaN(空)的用户数(行数)
----------------------------------------------------------------------------------------------------------------------------------------------------------------
一般来说比如我们想筛选出 discount_rate是20:1且distance不是1.0的行数可以这么做:
dfoff.info()
print('数目是:',dfoff[(dfoff['discount_rate']=='20:1')&(dfoff['Date']!=1.0)].shape[0])
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
于是笔者这样做了筛选:
dfoff.info()
print('有优惠券,但是没有使用优惠券购买的客户有',dfoff[(dfoff['Coupon_id']!='NaN')&(dfoff['Date']=='NaN')].shape[0])
结果报错:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1754884 entries,0 to 1754883
Data columns (total 7 columns):
User_id int64
Merchant_id int64
Coupon_id float64
discount_rate object
distance float64
Date_received float64
Date float64
dtypes: float64(4),int64(2),object(1)
memory usage: 93.7+ MB
/opt/conda/lib/python3.6/site-packages/pandas/core/ops.py:816: FutureWarning: elementwise comparison Failed; returning scalar instead,but in the future will perform elementwise comparison
result = getattr(x,name)(y)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-24-c27c94978405> in <module>()
1 dfoff.info()
----> 2 print('有优惠券,但是没有使用优惠券购买的客户有',dfoff[(dfoff['Coupon_id']!='NaN')&(dfoff['Date']=='NaN')].shape[0])
/opt/conda/lib/python3.6/site-packages/pandas/core/ops.py in wrapper(self,other,axis)
877
878 with np.errstate(all='ignore'):
--> 879 res = na_op(values,other)
880 if is_scalar(res):
881 raise TypeError('Could not compare {typ} type with Series'
/opt/conda/lib/python3.6/site-packages/pandas/core/ops.py in na_op(x,y)
816 result = getattr(x,name)(y)
817 if result is NotImplemented:
--> 818 raise TypeError("invalid type comparison")
819 except AttributeError:
820 result = op(x,y)
TypeError: invalid type comparison
其实吧原因很简单,注意看上面笔者故意标红的地方,Coupon_id 和Date的数据类型都是float64,而代码中却用了dfoff['Coupon_id']!='NaN',这不是字符串嘛!!!!!!
print(type('NaN'))
<class 'str'>
float和str比较当然报错了是吧,哎!能这样直接去比较我也算是极品啦哈哈哈
于是可以使用其内置的方法解决:
dfoff.info()
print('有优惠券,但是没有使用优惠券购买的客户有',dfoff[(dfoff['Coupon_id'].notnull())&(dfoff['Date'].isnull())].shape[0])
即使用了如下两个方法
.notnull()
.isnull()
其作用就是判断是否是空值,如果csv中的NaN的地方换成null同样适用
同时这里说一下怎么将NaN替换掉:例如替换成0.0
dfoff['Coupon_id']=dfoff['Coupon_id'].replace(np.nan,0.0)
-----------------------------------------------------------------------------------------------------------------------------------------------------------
下面来说一下NaN这个数据类型,它的全称应该是not a number,说到这里不得不提到另外一个数据类型inf
相同点:都是代表一个无法表示的数
不同点:inf代表无穷大,是一个超过浮点表示范围的浮点数,而NaN可以看成是缺少值或者是无理数
假设现在有一段程序:
def ConvertRate(row):
if row.isnull():
return 0
elif ':' in str(row):
rows = str(row).split(':')
return 1.0-float(rows[1])/float(rows[0])
else:
return float(row)
dfoff['discount_rate'] = dfoff['discount_rate'].apply(ConvertRate)
print(dfoff.head(3))
会发现报错:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-3-0aa06185ee75> in <module>()
7 else:
8 return float(row)
----> 9 dfoff['discount_rate'] = dfoff['discount_rate'].apply(ConvertRate)
10 print(dfoff.head(3))
/opt/conda/lib/python3.6/site-packages/pandas/core/series.py in apply(self,func,convert_dtype,args,**kwds)
2549 else:
2550 values = self.asobject
-> 2551 mapped = lib.map_infer(values,f,convert=convert_dtype)
2552
2553 if len(mapped) and isinstance(mapped[0],Series):
pandas/_libs/src/inference.pyx in pandas._libs.lib.map_infer()
<ipython-input-3-0aa06185ee75> in ConvertRate(row)
1 def ConvertRate(row):
----> 2 if row.isnull():
3 return 0
4 elif ':' in str(row):
5 rows = str(row).split(':')
AttributeError: 'float' object has no attribute 'isnull'
那它到底是什么数据类型呢?
print(type(np.nan))
print(type(np.inf))
<class 'float'>
<class 'float'>
NaN'就是表示一个普通的字符串,而np.nan就是代表真真的nan,那我们可不可以使用这样:
def ConvertRate(row):
if row==np.nan:
return 0
elif ':' in str(row):
rows = str(row).split(':')
return 1.0-float(rows[1])/float(rows[0])
else:
return float(row)
dfoff['discount_rate'] = dfoff['discount_rate'].apply(ConvertRate)
print(dfoff.head(3))
User_id Merchant_id Coupon_id discount_rate distance Date_received \
0 1439408 2632 NaN NaN 0.0 NaN
1 1439408 4663 11002.0 150:20 1.0 20160528.0
2 1439408 2632 8591.0 20:1 0.0 20160217.0
Date discount_rate
0 20160217.0 NaN
1 NaN 0.866667
2 NaN 0.950000
可以看到这里还是NaN,并不是0,说明还是不对
那试一下:
def ConvertRate(row):
if row==float('NaN'):
return 0
elif ':' in str(row):
rows = str(row).split(':')
return 1.0-float(rows[1])/float(rows[0])
else:
return float(row)
dfoff['discount_rate'] = dfoff['discount_rate'].apply(ConvertRate)
print(dfoff.head(3))
结果还是如上面,其实NaN数据类型就是一种特殊的float,这里相当于强制类型转化
那到底怎么办呢?其实判断是否是NaN可以使用如下方法:
row!=row
如果结果是真,那么就是NaN,假就代表不是NaN
可以看一下结果:
def ConvertRate(row):
if row!=row:
return 0
elif ':' in str(row):
rows = str(row).split(':')
return 1.0-float(rows[1])/float(rows[0])
else:
return float(row)
dfoff['discount_rate'] = dfoff['discount_rate'].apply(ConvertRate)
print(dfoff.head(3))
print(dfoff.head(3))
User_id Merchant_id Coupon_id discount_rate distance Date_received \
0 1439408 2632 NaN NaN 0.0 NaN
1 1439408 4663 11002.0 150:20 1.0 20160528.0
2 1439408 2632 8591.0 20:1 0.0 20160217.0
Date discount_rate
0 20160217.0 0.000000
1 NaN 0.866667
2 NaN 0.950000
于是笔者最开始的那个问题也可以这样解决:
print('有优惠券,但是没有使用优惠券购买的客户有',dfoff[(dfoff['Coupon_id']==dfoff['Coupon_id'])&(dfoff['Date']!=dfoff['Date'])].shape[0])
有优惠券,但是没有使用优惠券购买的客户有 977900
---------------------------------------------------------------------------------------------------------------------------------------------------------------
有时候在使用apply的时候会报错,所以最好加一下:axis = 1意思是按列处理的
对应到上面就是吧:
dfoff['discount_rate'] = dfoff['discount_rate'].apply(ConvertRate)
改为:
dfoff['discount_rate'] = dfoff['discount_rate'].apply(ConvertRate,axis = 1)
------------------------------------------------------------------------------------------------------------------------------------------------------------
所以最后总结一下:
NaN和inf都是一种特殊的float数据类型
可以使用row!=row类似的形式来判断是否是NaN,如果是真就代表是NaN,假就代表不是NaN,换句话说也可以使用row==row来判断是否是NaN,只不过逻辑相反而已
报错记得加axis = 1
------------------------------------------------------------------------------------------------------------------------------------------------------
在使用pands加载数据的时候,其实我们是可以控制数据类型的,比如让缺省值变为null,而不是NAN,即让字段的数据类型不再是float,而是object,这里有一个例子:https://blog.csdn.net/weixin_42001089/article/details/85013073
JavaScript Puzzlers! 解惑(一):为什么 ["1", "2", "3"].map(parseInt) 返回 [1,NaN,NaN]?
JavaScript Puzzlers! 被称为 javascript 界的专业八级测验,感兴趣的 jser 可以去试试。
我试了一下, 36 道题只做对了 19 道, 算下来正确率为 53%,还没有及格。
第一题为 ["1", "2", "3"].map(parseInt)
的返回值。
> ["1", "2", "3"].map(parseInt)
[1, NaN, NaN]
在 javascript 中 ["1", "2", "3"].map(parseInt)
为何返回不是 [1,2,3]
却是 [1,NaN,NaN]
?
我们首先回顾一下 parseInt()
个 map()
两个函数的用法:
parseInt() 函数
定义和用法
parseInt()
函数可解析一个字符串,并返回一个整数。
语法
parseInt(string, radix)
参数 | 描述 |
---|---|
string | 必需。要被解析的字符串。 |
radix |
可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。 如果省略该参数或其值为 `0`,则数字将以 10 为基础来解析。如果它以 `"0x"` 或 `"0X"` 开头,将以 16 为基数。 如果该参数小于 2 或者大于 36,则 `parseInt()` 将返回 `NaN`。 |
返回值
返回解析后的数字。
说明
当参数 radix
的值为 0
,或没有设置该参数时,parseInt()
会根据 string
来判断数字的基数。
举例:
如果
string
以"0x"
开头,parseInt()
会把string
的其余部分解析为十六进制的整数。如果
string
以0
开头,那么 ECMAScript v3 允许parseInt()
的一个实现把其后的字符解析为八进制或十六进制的数字。如果
string
以 1 ~ 9 的数字开头,parseInt()
将把它解析为十进制的整数。
提示和注释
注释:只有字符串中的第一个数字会被返回。
注释:开头和结尾的空格是允许的。
提示:如果字符串的第一个字符不能被转换为数字,那么 parseInt()
会返回 NaN
。
实例
在本例中,我们将使用 parseInt()
来解析不同的字符串:
parseInt("10"); // 返回 10 (默认十进制)
parseInt("19",10); // 返回 19 (十进制: 10+9)
parseInt("11",2); // 返回 3 (二进制: 2+1)
parseInt("17",8); // 返回 15 (八进制: 8+7)
parseInt("1f",16); // 返回 31 (十六进制: 16+15)
parseInt("010"); // 未定:返回 10 或 8
map 方法
对数组的每个元素调用定义的回调函数并返回包含结果的数组。
array1.map(callbackfn[, thisArg])
参数 | 定义 |
---|---|
array1 | 必需。一个数组对象。 |
callbackfn | 必需。一个接受**最多**三个参数的函数。对于数组中的每个元素,`map` 方法都会调用 `callbackfn` 函数一次。 |
thisArg | 可选。可在 `callbackfn` 函数中为其引用 `this` 关键字的对象。如果省略 `thisArg`,则 `undefined` 将用作 `this` 值。 |
返回值
其中的每个元素均为关联的原始数组元素的回调函数返回值的新数组。
异常
如果 callbackfn
参数不是函数对象,则将引发 TypeError
异常。
备注
对于数组中的每个元素,map
方法都会调用 callbackfn
函数一次(采用升序索引顺序)。 不为数组中缺少的元素调用该回调函数。
除了数组对象之外,map
方法可由具有 length
属性且具有已按数字编制索引的属性名的任何对象使用。
回调函数语法
回调函数的语法如下所示:
function callbackfn(value, index, array1)
可使用最多三个参数来声明回调函数。
下表列出了回调函数参数。
回调参数 | 定义 |
---|---|
value | 数组元素的值。 |
index | 数组元素的数字索引。 |
array1 | 包含该元素的数组对象。 |
修改数组对象
数组对象可由回调函数修改。
下表描述了在 map
方法启动后修改数组对象所获得的结果。
`map` 方法启动后的条件 | 元素是否传递给回调函数 |
---|---|
在数组的原始长度之外添加元素。 | 否。 |
添加元素以填充数组中缺少的元素。 | 是,如果该索引尚未传递给回调函数。 |
元素被更改。 | 是,如果该元素尚未传递给回调函数。 |
从数组中删除元素。 | 否,除非该元素已传递给回调函数。 |
示例
下面的示例阐释了 map
方法的用法。
// 定义回调函数
// 计算圆的面积
function AreaOfCircle(radius) {
var area = Math.PI * (radius * radius);
return area.toFixed(0);
}
// 定义一个数组,保护三个元素
var radii = [10, 20, 30];
// 计算 radii 的面积.
var areas = radii.map(AreaOfCircle);
document.write(areas);
// 输出:
// 314,1257,2827
下面的示例阐释 thisArg
参数的用法,该参数指定对其引用 this
关键字的对象。
// 定义一个对象 object,保护 divisor 属性和 remainder 方法
// remainder 函数求每个传入的值的个位数。(即除以 10 取余数)
var obj = {
divisor: 10,
remainder: function (value) {
return value % this.divisor;
}
}
// 定义一个包含 4 个元素的数组
var numbers = [6, 12, 25, 30];
// 对 numbers 数组的每个元素调用 obj 对象的 remainder 函数。
// map 函数的第 2 个参数传入 ogj。
var result = numbers.map(obj.remainder, obj);
document.write(result);
// 输出:
// 6,2,5,0
在下面的示例中,内置 JavaScript 方法用作回调函数。
// 对数组中的每个元素调用 Math.sqrt(value) (求平方根)
var numbers = [9, 16];
var result = numbers.map(Math.sqrt);
document.write(result);
// 输出: 3,4
[9, 16].map(Math.sqrt)
回调函数,输出的结果是 [3, 4]
。
但是为什么 ["1", "2", "3"].map(parseInt)
却返回 [1,NaN,NaN]
?
网站给出的提示是:
what you actually get is
[1, NaN, NaN]
becauseparseInt
takes two parameters(val, radix)
andmap
passes 3(element, index, array)
简单翻译一下就是
parseInt
需要 2 个参数(val, radix)
, 而map
传递了 3 个参数(element, index, array)
」。
通过上面的解释,我们可以看出,如果想让 parseInt(string, radix)
返回 NaN,有两种情况:
第一个参数不能转换成数字。
第二个参数不在 2 到 36 之间。
我们传入的参数都能转换成数字,所以只能是第二种可能。
到底是不是呢?我们重新定义 parseInt(string, radix)
函数:
var parseInt = function(string, radix) {
return string + "-" + radix;
};
["1", "2", "3"].map(parseInt);
输出结果为:
["1-0", "2-1", "3-2"]
看见,map
函数将数组的值 value
传递给了 parseInt
的第一个参数,将数组的索引传递给了第二个参数。
第三个参数呢?我们再加一个参数
var parseInt = function(string, radix, obj) {
return string + "-" + radix + "-" + obj;
};
["1", "2", "3"].map(parseInt);
输出结果:
["1-0-1,2,3", "2-1-1,2,3", "3-2-1,2,3"]
我们再继续增加参数:
var parseInt = function(string, radix, obj, other) {
return string + "-" + radix + "-" + obj + "-" + other;
};
["1", "2", "3"].map(parseInt);
输出结果:
["1-0-1,2,3-undefined", "2-1-1,2,3-undefined", "3-2-1,2,3-undefined"]
第四个参数为 undefined
,看见 map
确实为 parseInt
传递了三个参数。就像作者写道的:
(element, index, array)
数组的值
数组的索引
数组
UPDATE 原文勘误:(谢谢 米粽粽 提醒)
["1", "2", "3"].map(parseInt)
应该对应的是:
[parseInt("1", 0), parseInt("2", 1), parseInt("3", 2)]
parseInt("3", 2)
的第二个参数是界于 2-36 之间的,之所以返回 NaN
是因为 字符串 "3"
里面没有合法的二进制数,所以 NaN
。
我们还可以继续试验:
> ["1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"].map(parseInt)
[1, NaN, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
只有当第二个参数是 1
的时候返回 NaN
,其它情况都返回 1
。
> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"].map(parseInt)
[1, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, 9, 11, 13, 15, 17, 19, 21]
简单列举一下:
parseInt("1", 0); // 十进制 1
parseInt("2", 1); // 第二个参数不在 2-36 直接
parseInt("3", 2); // 二进制 NaN
parseInt("4", 3); // 三进制
parseInt("5", 4);
parseInt("6", 5);
parseInt("7", 6);
parseInt("8", 7);
parseInt("9", 8);
parseInt("10", 9); // 九进制 (1*9+0 = 9)
parseInt("11", 10); // 十进制 (1*10+1 = 11)
parseInt("12", 11);
parseInt("13", 12);
parseInt("14", 13);
parseInt("15", 14);
parseInt("16", 15);
(全文完)
文章来自我的个人博客:JavaScript Puzzlers 解密(一):为什么 ["1", "2", "3"].map(parseInt) 返回 [1, NaN, NaN]?
numpy.random.random & numpy.ndarray.astype & numpy.arange
今天看到这样一句代码:
xb = np.random.random((nb, d)).astype(''float32'') #创建一个二维随机数矩阵(nb行d列)
xb[:, 0] += np.arange(nb) / 1000. #将矩阵第一列的每个数加上一个值
要理解这两句代码需要理解三个函数
1、生成随机数
numpy.random.random(size=None)
size为None时,返回float。
size不为None时,返回numpy.ndarray。例如numpy.random.random((1,2)),返回1行2列的numpy数组
2、对numpy数组中每一个元素进行类型转换
numpy.ndarray.astype(dtype)
返回numpy.ndarray。例如 numpy.array([1, 2, 2.5]).astype(int),返回numpy数组 [1, 2, 2]
3、获取等差数列
numpy.arange([start,]stop,[step,]dtype=None)
功能类似python中自带的range()和numpy中的numpy.linspace
返回numpy数组。例如numpy.arange(3),返回numpy数组[0, 1, 2]
关于NumPy 或 Pandas:将数组类型保持为整数,同时具有 NaN 值和怎么把numpy数组里的数都改成int型的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于"CALayer position contains NaN: [nan nan]" 自定义滑块导致的错误信息、/opt/conda/lib/python3.6/site-packages/pandas/core/ops.py:816: pandas 处理 NaN、JavaScript Puzzlers! 解惑(一):为什么 ["1", "2", "3"].map(parseInt) 返回 [1,NaN,NaN]?、numpy.random.random & numpy.ndarray.astype & numpy.arange等相关知识的信息别忘了在本站进行查找喔。
本文标签: