Python Pandas 成对频率 Table 有很多列
Python Pandas Pairwise Frequency Table with many columns
初学者 Pandas 问题在这里:
如何为所有列创建交叉频率计数 table? 我想使用输出来制作一个 seaborn 热图图,显示每对之间的计数列数。
我有一个数据框(使用 pyspark 从 hdfs 中提取),其中包含约 70 个唯一列和大约 60 万行
示例所需输出:
C1 C2 C3 C4 ...C70
C1 - 1 1 2
C2 1 - 0 2
C3 1 0 - 1
C4 2 2 1 -
...
C70
样本 DF:
import numpy as np
import pandas as pd
raw_data = {'C1': [ 0, 2, 5, 0, 3], #...600K
'C2': [3, 0 , 2, 0, 0],
'C3': [0, 0, 0, 3, 3],
'C4': [2, 1, 1, 4, 0]}
df = pd.DataFrame(raw_data, columns = ['C1', 'C2', 'C3','C4'])
print(df)
我尝试使用 pandas 中的交叉表、数据透视表、pivot_table 并认为解决方案是使用交叉表,但我无法以所需的输出格式获得它(抱歉,如果有很明显我错过了)。感谢任何帮助!
用 clip_upper
将正值截取到 1
,然后计算点积:
i = df.clip_upper(1)
j = i.T.dot(i)
j
C1 C2 C3 C4
C1 3 1 1 2
C2 1 2 0 2
C3 1 0 2 1
C4 2 2 1 4
这是一个使用 spark-sql
的 PySpark DataFrame 解决方案。绝对不如 @cᴏʟᴅsᴘᴇᴇᴅ 的 pandas 解决方案优雅,但也许这对真正的大数据帧很有用。
假设您的数据位于 PySpark DataFrame spark_df
中。
spark_df.show()
#+---+---+---+---+
#| C1| C2| C3| C4|
#+---+---+---+---+
#| 0| 3| 0| 2|
#| 2| 0| 0| 1|
#| 5| 2| 0| 1|
#| 0| 0| 3| 4|
#| 3| 0| 3| 0|
#+---+---+---+---+
创建一个空的 DataFrame 来保存输出。此模式将是一个 StringType()
列,然后是 spark_df
中每一列的 IntegerType()
列:
cols = spark_df.columns
schema = StructType(
[StructField('col', StringType())] + [StructField(c, IntegerType()) for c in cols]
)
output = sqlCtx.createDataFrame([], schema=schema)
output.printSchema()
#root
# |-- col: string (nullable = true)
# |-- C1: long (nullable = true)
# |-- C2: long (nullable = true)
# |-- C3: long (nullable = true)
# |-- C4: long (nullable = true)
将此 DataFrame 注册为 table:
spark_df.registerTempTable('table')
遍历 DataFrame 中的每一列并构建查询以获取该 "row" 的值。使用 union()
.
将查询的输出添加到 output
for col in cols:
q = "SELECT '%s' AS col," % col
q += ",".join("SUM(CASE WHEN %s > 0 AND %s > 0 THEN 1 ELSE 0 END) AS %s " % (col, c, c) for c in cols)
q += " FROM table t"
output = output.union(sqlCtx.sql(q))
最后输出:
output.show()
#+---+---+---+---+---+
#|col| C1| C2| C3| C4|
#+---+---+---+---+---+
#| C1| 3| 1| 1| 2|
#| C2| 1| 2| 0| 2|
#| C3| 1| 0| 2| 1|
#| C4| 2| 2| 1| 4|
#+---+---+---+---+---+
与 pandas 版本匹配。
初学者 Pandas 问题在这里:
如何为所有列创建交叉频率计数 table? 我想使用输出来制作一个 seaborn 热图图,显示每对之间的计数列数。
我有一个数据框(使用 pyspark 从 hdfs 中提取),其中包含约 70 个唯一列和大约 60 万行
示例所需输出:
C1 C2 C3 C4 ...C70
C1 - 1 1 2
C2 1 - 0 2
C3 1 0 - 1
C4 2 2 1 -
...
C70
样本 DF:
import numpy as np
import pandas as pd
raw_data = {'C1': [ 0, 2, 5, 0, 3], #...600K
'C2': [3, 0 , 2, 0, 0],
'C3': [0, 0, 0, 3, 3],
'C4': [2, 1, 1, 4, 0]}
df = pd.DataFrame(raw_data, columns = ['C1', 'C2', 'C3','C4'])
print(df)
我尝试使用 pandas 中的交叉表、数据透视表、pivot_table 并认为解决方案是使用交叉表,但我无法以所需的输出格式获得它(抱歉,如果有很明显我错过了)。感谢任何帮助!
用 clip_upper
将正值截取到 1
,然后计算点积:
i = df.clip_upper(1)
j = i.T.dot(i)
j
C1 C2 C3 C4
C1 3 1 1 2
C2 1 2 0 2
C3 1 0 2 1
C4 2 2 1 4
这是一个使用 spark-sql
的 PySpark DataFrame 解决方案。绝对不如 @cᴏʟᴅsᴘᴇᴇᴅ 的 pandas 解决方案优雅,但也许这对真正的大数据帧很有用。
假设您的数据位于 PySpark DataFrame spark_df
中。
spark_df.show()
#+---+---+---+---+
#| C1| C2| C3| C4|
#+---+---+---+---+
#| 0| 3| 0| 2|
#| 2| 0| 0| 1|
#| 5| 2| 0| 1|
#| 0| 0| 3| 4|
#| 3| 0| 3| 0|
#+---+---+---+---+
创建一个空的 DataFrame 来保存输出。此模式将是一个 StringType()
列,然后是 spark_df
中每一列的 IntegerType()
列:
cols = spark_df.columns
schema = StructType(
[StructField('col', StringType())] + [StructField(c, IntegerType()) for c in cols]
)
output = sqlCtx.createDataFrame([], schema=schema)
output.printSchema()
#root
# |-- col: string (nullable = true)
# |-- C1: long (nullable = true)
# |-- C2: long (nullable = true)
# |-- C3: long (nullable = true)
# |-- C4: long (nullable = true)
将此 DataFrame 注册为 table:
spark_df.registerTempTable('table')
遍历 DataFrame 中的每一列并构建查询以获取该 "row" 的值。使用 union()
.
output
for col in cols:
q = "SELECT '%s' AS col," % col
q += ",".join("SUM(CASE WHEN %s > 0 AND %s > 0 THEN 1 ELSE 0 END) AS %s " % (col, c, c) for c in cols)
q += " FROM table t"
output = output.union(sqlCtx.sql(q))
最后输出:
output.show()
#+---+---+---+---+---+
#|col| C1| C2| C3| C4|
#+---+---+---+---+---+
#| C1| 3| 1| 1| 2|
#| C2| 1| 2| 0| 2|
#| C3| 1| 0| 2| 1|
#| C4| 2| 2| 1| 4|
#+---+---+---+---+---+
与 pandas 版本匹配。