我有一个带有ID的列,时间在其中编码.例如:
0 020160910223200_T1
1 020160910223200_T1
2 020160910223203_T1
3 020160910223203_T1
4 020160910223206_T1
5 020160910223206_T1
6 020160910223209_T1
7 020160910223209_T1
8 020160910223213_T1
9 020160910223213_T1
Run Code Online (Sandbox Code Playgroud)
如果我们删除第一个和最后三个字符,我们获得第一行:20160910223200,应该转换为2016-09-10 22:32:00.
我的解决方案是编写一个截断ID并转换为日期时间的函数.然后,我将此函数应用于我的df列.
from datetime import datetime
def MeasureIDtoTime(MeasureID):
MeasureID = str(MeasureID)
MeasureID = MeasureID[1:14]
Time = datetime.strptime(MeasureID, '%Y%m%d%H%M%S')
return Time
df['Time'] = df['MeasureID'].apply(MeasureIDtoTime)
Run Code Online (Sandbox Code Playgroud)
这可以正常工作,但对我的情况来说速度很慢.我必须处理超过2000万行,我需要更快的解决方案.想要更高效的解决方案吗?
更新
根据@MaxU,有一个更好的解决方案:
pd.to_datetime(df.ID.str[1:-3], format = '%Y%m%d%H%M%S')
Run Code Online (Sandbox Code Playgroud)
对于720万行,这可以在32秒内完成工作.但是,在R中,由于lubridate::ymd_hms()功能,我在不到2秒的时间内完成了任务.所以我想知道在Python中是否存在更好的解决方案.
假设我们有3个方法都返回一个 Option
import scala.util.Try
def divideSafe(d: Int): Option[Int] = Try(42 / d).toOption
def sqrtSafe(x: Double): Option[Double] = if(!math.sqrt(x).isNaN) Some(math.sqrt(x)) else None
def convertSafe(s: String): Option[Int] = Try(s.toInt).toOption
Run Code Online (Sandbox Code Playgroud)
现在,我想在条件成立时将它们链接起来。就我而言,如果定义了前一个方法的结果,则应转到下一个方法。并且只要条件为假,就停止操作并返回默认值。
我可以使用嵌套的if-else语句获得所需的结果:
def superSafe(d: Int, x: Double, s: String): Unit = {
if (divideSafe(d).isDefined) {
println(divideSafe(d).get.toString)
if (sqrtSafe(x).isDefined) {
println(sqrtSafe(x).toString)
if (convertSafe(s).isDefined) {
println(convertSafe(s).get.toString)
} else {
println("Converting failed")
}
} else {
println("Sqrt failed")
}
} else {
println("Dividing failed")
}
}
Run Code Online (Sandbox Code Playgroud)
因此:
superSafe(1, -1, "5")将打印42而Sqrt失败
superSafe(0, 4, "cat")将打印除法失败
superSafe(42, …
假设我们有一个数组:
val arr = Array("Id:1; Apple; Red; 2; Out",
"Id:2; Banana; Yellow; 5",
"Id:3; Peach; Red; 3",
"Id:4; Grape; Green; 5; Out")
Run Code Online (Sandbox Code Playgroud)
我想在数组的每个元素上应用一个函数,它提取水果类型和数字并返回一个Map.这种情况下的输出是:
(Apple, 2)
(Banana, 5)
(Peach, 3)
(Grape, 5)
Run Code Online (Sandbox Code Playgroud)
我试过了:
val pairMap = arr.foreach(r => r.split(";")(1) zip r.split(";")(3))
Run Code Online (Sandbox Code Playgroud)
但我总是得到 Unit
假设我们有一个序列 Any
val seq = Seq(1,2,null)
seq: Seq[Any] = List(1, 2, null)
Run Code Online (Sandbox Code Playgroud)
现在,如果一个过滤器非空元素获得一个新的序列
val cleanSeq = seq.filterNot(_ == null)
cleanSeq: Seq[Any] = List(1, 2)
Run Code Online (Sandbox Code Playgroud)
现在,我想获得与创建新序列时获得的类型相同的类型,例如 cleanSeq
val seq2 = Seq(1,2)
seq2: Seq[Int] = List(1, 2)
Run Code Online (Sandbox Code Playgroud)
我可以Seq[Int]从 开始以某种方式获得cleanSeq吗?
更新
前一个只是一个虚拟示例,我可以有其他类型而不是Int复杂类型示例:Array[Map[String, Float]].
我能做的唯一假设是我有一个可能包含空值的序列。但是序列中的其他元素除了Any. 删除空值后,我想找到常见的超类型。
更新
用例
我想从具有名称和值的列创建一个火花数据框。这些值存储在一个Seq. 从Seq我想派生数据框的模式的类型。
列的定义
import reflect.runtime.universe._
import org.apache.spark.sql.catalyst.ScalaReflection
import org.apache.spark.sql.types._
case class InternalColumn[A: TypeTag](colName: String, col: Seq[A]) {
private def getType: DataType = …Run Code Online (Sandbox Code Playgroud)