- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有将近 50 万个包含时间序列数据的 XML 文件,每个文件大约 2-3MB,每个文件包含大约 10k 行时间序列数据。这个想法是将每个唯一 ID 的 XML 文件转换为 JSON。但是,每个ID的时间序列数据需要分解成行大小为10的批处理并转换为JSON并写入NoSQL数据库。最初,编写的代码是为每个 ID 迭代一个整体数据帧,并按行大小 10 递增,然后将文档写入数据库。
def resample_idx(X,resample_rate):
for idx in range(0,len(X),resample_rate):
yield X.iloc[idx:idx+resample_rate,:]
# Batch Documents
for idx, df_batch in enumerate(resample_idx(df,10))
dict_ = {}
dict_['id'] = soup.find('id').contents[0]
dict_['data'] = [v for k,v in pd.DataFrame.to_dict(df_batch.T).items()]
JSON 文档的示例如下所示:
{'id':123456A,
'data': [{'A': 251.23,
'B': 130.56,
'dtim': Timestamp('2011-03-24 11:18:13.350000')
},
{
'A': 253.23,
'B': 140.56,
'dtim': Timestamp('2011-03-24 11:19:21.310000')
},
.........
]
},
{'id':123593X,
'data': [{'A': 641.13,
'B': 220.51,
'C': 10.45
'dtim': Timestamp('2011-03-26 12:11:13.350000')
},
{
'A': 153.25,
'B': 810.16,
'C': 12.5
'dtim': Timestamp('2011-03-26 12:11:13.310000')
},
.........
]
}
这适用于小样本,但很快意识到这在创建批处理时无法扩展。因此,希望在 Spark 中复制它。使用 Spark 的经验有限,但这是我到目前为止所做的尝试:
首先获取所有ID的所有时间序列数据:
df = sqlContext.read.format("com.databricks.spark.xml").options(rowTag='log').load("dbfs:/mnt/timedata/")
XML 模式
|-- _id: string (nullable = true)
|-- collect_list(TimeData): array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- data: array (nullable = true)
| | | |-- element: string (containsNull = true)
| | |-- ColNames: string (nullable = true)
| | |-- Units: string (nullable = true)
获取 Spark DataFrame 的 SQL 查询 d = df.select("_id","TimeData.data",'TimeData.ColNames')
当前的 Spark 数据帧
+--------------------+--------------------+--------------------+
| id | data| ColNames|
+--------------------+--------------------+--------------------+
|123456A |[2011-03-24 11:18...|dTim,A,B |
|123456A |[2011-03-24 11:19...|dTim,A,B |
|123593X |[2011-03-26 12:11...|dTim,A,B,C |
|123593X |[2011-03-26 12:11...|dTim,A,B,C |
+--------------------+--------------------+--------------------+
预期的 Spark 数据帧
+--------------------+--------------------+----------+----------+
| id | dTime| A| B|
+--------------------+--------------------+----------+----------+
|123456A |2011-03-24 11:18... | 251.23| 130.56|
|123456A |2011-03-24 11:19... | 253.23| 140.56|
+--------------------+--------------------+----------+----------+
+--------------------+--------------------+----------+----------+----------+
| id | dTime| A| B| C|
+--------------------+--------------------+----------+----------+----------+
|123593X |2011-03-26 12:11... | 641.13| 220.51| 10.45|
|123593X |2011-03-26 12:11... | 153.25| 810.16| 12.5|
+--------------------+-------------------+---------- +----------+----------+
我在这里只显示了两个时间戳的数据,但是我如何才能将上面的 DataFrame 转换为每第 n 行(对于每个 id)的批处理 JSON 文件,类似于上面显示的使用 Pandas 完成的方式?最初的想法是执行 groupBy 并将 UDF 应用于每个 ID?输出类似于上面的 JSON 结构。
XML 结构:
<log>
<id>"ABC"</id>
<TimeData>
<colNames>dTim,colA,colB,colC,</colNames>
<data>2011-03-24T11:18:13.350Z,0.139,38.988,0,110.307</data>
<data>2011-03-24T11:18:43.897Z,0.138,39.017,0,110.307</data>
</TimeData>
</log>
请注意,每个 ID 没有固定数量的 coNames,范围可以在 5-30 之间,具体取决于为该 ID 收集的数据源。
最佳答案
嗯,根据信息,这可能是一个解决方案。不幸的是,我的 Python 有点生疏,但这里应该有所有 Scala 函数的等价物
// Assume nth is based of dTim ordering
val windowSpec = Window
.partitionBy($"_id")
.orderBy($"dTim".desc)
val nthRow = 2 // define the nthItem to be fetched
df.select(
$"_id",
$"TimeData.data".getItem(0).getItem(0).cast(TimestampType).alias("dTim"),
$"TimeData.data".getItem(0).getItem(1).cast(DoubleType).alias("A"),
$"TimeData.data".getItem(0).getItem(2).cast(DoubleType).alias("B"),
$"TimeData.data".getItem(0).getItem(3).cast(DoubleType).alias("C")
).withColumn("n", row_number().over(windowSpec))
.filter(col("n") === nthRow)
.drop("n")
.show()
会输出类似的东西
+-------+--------------------+------+------+-----+
| _id| dTim| A| B| C|
+-------+--------------------+------+------+-----+
|123456A|2011-03-24 11:18:...|251.23|130.56| null|
|123593X|2011-03-26 12:11:...|641.13|220.51|10.45|
+-------+--------------------+------+------+-----+
如果我知道更多,我会改进答案
更新
我喜欢这个谜题,所以如果我正确理解问题,这可能是一个解决方案:
我创建了 3 个 xml 文件,每 2 个数据记录总共有 2 个不同的 id
val df = spark
.sqlContext
.read
.format("com.databricks.spark.xml")
.option("rowTag", "log")
.load("src/main/resources/xml")
// Could be computationally heavy, maybe cache df first if possible, otherwise run it on a sample, otherwise hardcode possible colums
val colNames = df
.select(explode(split($"TimeData.colNames",",")).as("col"))
.distinct()
.filter($"col" =!= lit("dTim") && $"col" =!= "")
.collect()
.map(_.getString(0))
.toList
.sorted
// or list all possible columns
//val colNames = List("colA", "colB", "colC")
// Based on XML colNames and data are comma seprated strings that have to be split. Could be done using sql split function, but this UDF maps the columns to the correct field
def mapColsToData = udf((cols:String, data:Seq[String]) =>
if(cols == null || data == null) Seq.empty[Map[String, String]]
else {
data.map(str => (cols.split(",") zip str.split(",")).toMap)
}
)
// The result of this action is 1 record for each datapoint for all XML's. Each data record is key->value map of colName->data
val denorm = df.select($"id", explode(mapColsToData($"TimeData.colNames", $"TimeData.data")).as("data"))
denorm.show(false)
输出:
+-------+-------------------------------------------------------------------------------+
|id |data |
+-------+-------------------------------------------------------------------------------+
|123456A|Map(dTim -> 2011-03-24T11:18:13.350Z, colA -> 0.139, colB -> 38.988, colC -> 0)|
|123456A|Map(dTim -> 2011-03-24T11:18:43.897Z, colA -> 0.138, colB -> 39.017, colC -> 0)|
|123593X|Map(dTim -> 2011-03-26T11:20:13.350Z, colA -> 1.139, colB -> 28.988) |
|123593X|Map(dTim -> 2011-03-26T11:20:43.897Z, colA -> 1.138, colB -> 29.017) |
|123456A|Map(dTim -> 2011-03-27T11:18:13.350Z, colA -> 0.129, colB -> 35.988, colC -> 0)|
|123456A|Map(dTim -> 2011-03-27T11:18:43.897Z, colA -> 0.128, colB -> 35.017, colC -> 0)|
+-------+-------------------------------------------------------------------------------+
// now create column for each map value, based on predef / found columnNames
val columized = denorm.select(
$"id",
$"data.dTim".cast(TimestampType).alias("dTim"),
$"data"
)
columized.show()
输出:
+-------+--------------------+--------------------+
| id| dTim| data|
+-------+--------------------+--------------------+
|123456A|2011-03-24 12:18:...|Map(dTim -> 2011-...|
|123456A|2011-03-24 12:18:...|Map(dTim -> 2011-...|
|123593X|2011-03-26 12:20:...|Map(dTim -> 2011-...|
|123593X|2011-03-26 12:20:...|Map(dTim -> 2011-...|
|123456A|2011-03-27 13:18:...|Map(dTim -> 2011-...|
|123456A|2011-03-27 13:18:...|Map(dTim -> 2011-...|
+-------+--------------------+--------------------+
// create window over which to resample
val windowSpec = Window
.partitionBy($"id")
.orderBy($"dTim".desc)
val resampleRate = 2
// add batchId based on resample rate. Group by batch and
val batched = columized
.withColumn("batchId", floor((row_number().over(windowSpec) - lit(1)) / lit(resampleRate)))
.groupBy($"id", $"batchId")
.agg(collect_list($"data").as("data"))
.drop("batchId")
batched.show(false)
输出:
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|id |data |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|123593X|[Map(dTim -> 2011-03-26T11:20:43.897Z, colA -> 1.138, colB -> 29.017), Map(dTim -> 2011-03-26T11:20:13.350Z, colA -> 1.139, colB -> 28.988)] |
|123456A|[Map(dTim -> 2011-03-27T11:18:43.897Z, colA -> 0.128, colB -> 35.017, colC -> 0), Map(dTim -> 2011-03-27T11:18:13.350Z, colA -> 0.129, colB -> 35.988, colC -> 0)]|
|123456A|[Map(dTim -> 2011-03-24T11:18:43.897Z, colA -> 0.138, colB -> 39.017, colC -> 0), Map(dTim -> 2011-03-24T11:18:13.350Z, colA -> 0.139, colB -> 38.988, colC -> 0)]|
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
// Store as 1 huge json file (drop reapatrition if you can handle multiple json, better for master as well)
batched.repartition(1).write.mode(SaveMode.Overwrite).json("/tmp/xml")
输出json:
{"id":"123593X","data":[{"dTim":"2011-03-26T12:20:43.897+01:00","colA":"1.138","colB":"29.017"},{"dTim":"2011-03-26T12:20:13.350+01:00","colA":"1.139","colB":"28.988"}]}
{"id":"123456A","data":[{"dTim":"2011-03-27T13:18:43.897+02:00","colA":"0.128","colB":"35.017","colC":"0"},{"dTim":"2011-03-27T13:18:13.350+02:00","colA":"0.129","colB":"35.988","colC":"0"}]}
{"id":"123456A","data":[{"dTim":"2011-03-24T12:18:43.897+01:00","colA":"0.138","colB":"39.017","colC":"0"},{"dTim":"2011-03-24T12:18:13.350+01:00","colA":"0.139","colB":"38.988","colC":"0"}]}
关于python - PySpark XML 到带时间序列数据的 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49967984/
我正在阅读 Python 文档以真正深入了解 Python 语言,并遇到了 filter 和 map 函数。我以前使用过过滤器,但从未使用过映射,尽管我在 SO 上的各种 Python 问题中都见过这
当我尝试打印 BST 的级别顺序时,这个问题提示了我。 这是一个 Pre-Order Sequence: 4, 1, 2, 3, 5, 6, 7, 8 In_order Sequence : 1, 2
我的代码在 main(序列测试;)的第一行出现错误,指出它是对 sequence::sequence() 的 undefined reference 。我无法更改 main 中的代码。有谁知道我该如何
这可能很简单,但我在通常的 latex 指南中找不到任何相关内容。在这句话中: {\em hello\/} “\/”的目的是什么? 最佳答案 这就是所谓的斜体校正。其目的是确保斜体文本后有适当的间距。
当我从 Postgresql 表中删除所有记录,然后尝试重置序列以在插入时开始一个编号为 1 的新记录时,我得到不同的结果: SELECT setval('tblname_id_seq', (SELE
在版本10.0.3中,MariaDB引入了一种称为序列的存储引擎。 其ad hoc为操作生成整数序列,然后终止。 该序列包含正整数,以降序或升序排列,并使用起始,结束和递增值。 它不允许在多个查询中
如何在 Groovy 中获取给定数字的序列,例如: def number = 169 // need a method in groovy to find the consecutive number
基本上,如果这是 .NET,它看起来像这样: ISomething { string A { get; } int B { get; } } var somethings = new List
说以下代码部分(同一块): A <= 1 A <= 2 变量 A 总是被赋值为 2 吗?还是会出现竞争条件并分配 1 或 2? 我对非阻塞赋值的理解是,由硬件在 future 分配变量 A,因此它可能
在运行 WiX 设置时,我正在寻找操作列表及其顺序。不知何故,官方网站似乎没有提供任何信息。 基本问题是我想正确安排我的自定义操作。通常我需要使用 regsvr32.exe 注册一个 DLL,而这只能
F#初学者在这里 我想创建一个类型,它是具有至少一个元素的另一种具体类型(事件)的序列。任何其他元素都可以在以后随时添加。通常在 C# 中,我会创建一个具有私有(private) List 和公共(p
作为构建过程和不断发展的数据库的一部分,我试图创建一个脚本,该脚本将删除用户的所有表和序列。我不想重新创建用户,因为这将需要比所允许的更多的权限。 我的脚本创建了一个过程来删除表/序列,执行该过程,然
我想恢复两个向量的第一个日期和相同向量的第二个日期之间的日期序列,.... 这是一个例子: dates1 = as.Date(c('2015-10-01', '2015-03-27', '2015-0
这个问题已经有答案了: sql ORDER BY multiple values in specific order? (12 个回答) 已关闭 9 年前。 我有一个 sql 语句,我想要ORDER
我想恢复两个向量的第一个日期和相同向量的第二个日期之间的日期序列,.... 这是一个例子: dates1 = as.Date(c('2015-10-01', '2015-03-27', '2015-0
在用java编写代码时,我需要用“],[”分割字符串。下面是我的代码。 try (BufferedReader reader = new BufferedReader(new InputStreamR
这个问题已经有答案了: Project Euler Question 14 (Collatz Problem) (8 个回答) 已关闭 9 年前。 我正在尝试查找数字的 Collatz 序列。以下
我有一个例程函数process_letter_location(const char& c, string &word)。 在我的 main 中,我声明了一系列字符串变量,如下所示: string s
我需要找到最长的多米诺骨牌链,给定一组 12 个随机挑选的多米诺骨牌。我已经递归地生成了多米诺骨牌的所有可能性(使用 0 到 12 的面值有 91 种可能性)。多米诺骨牌由一 block “砖 blo
我有这个数据结构 Seq,它继承了类 vector 但有一些额外的功能。使用这个数据结构 Seq 我有这个预定义的数据结构: typedef Seq > MxInt2d; 我现在想要一个包含多个 Mx
我是一名优秀的程序员,十分优秀!