How to use PyCall in Julia to convert Python output to Julia DataFrame
我想从
我认为使用
我尝试了以下内容。
1 2 3 4 | using PyCall, DataFrames @pyimport quandl data = quandl.get("WIKI/AAPL", returns ="pandas"); |
Julia将此输出转换为
如何让
谢谢你的任何建议!
这是一个选项:
首先,从
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | julia> colnames = map(Symbol, data[:columns]); 12-element Array{Symbol,1}: :Open :High :Low :Close :Volume Symbol("Ex-Dividend") Symbol("Split Ratio") Symbol("Adj. Open") Symbol("Adj. High") Symbol("Adj. Low") Symbol("Adj. Close") Symbol("Adj. Volume") |
然后将所有列倒入DataFrame:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | julia> y = DataFrame(Any[Array(data[c]) for c in colnames], colnames) 6×12 DataFrames.DataFrame │ Row │ Open │ High │ Low │ Close │ Volume │ Ex-Dividend │ Split Ratio │ ├─────┼───────┼───────┼───────┼───────┼──────────┼─────────────┼─────────────┤ │ 1 │ 28.75 │ 28.87 │ 28.75 │ 28.75 │ 2.0939e6 │ 0.0 │ 1.0 │ │ 2 │ 27.38 │ 27.38 │ 27.25 │ 27.25 │ 785200.0 │ 0.0 │ 1.0 │ │ 3 │ 25.37 │ 25.37 │ 25.25 │ 25.25 │ 472000.0 │ 0.0 │ 1.0 │ │ 4 │ 25.87 │ 26.0 │ 25.87 │ 25.87 │ 385900.0 │ 0.0 │ 1.0 │ │ 5 │ 26.63 │ 26.75 │ 26.63 │ 26.63 │ 327900.0 │ 0.0 │ 1.0 │ │ 6 │ 28.25 │ 28.38 │ 28.25 │ 28.25 │ 217100.0 │ 0.0 │ 1.0 │ │ Row │ Adj. Open │ Adj. High │ Adj. Low │ Adj. Close │ Adj. Volume │ ├─────┼───────────┼───────────┼──────────┼────────────┼─────────────┤ │ 1 │ 0.428364 │ 0.430152 │ 0.428364 │ 0.428364 │ 1.17258e8 │ │ 2 │ 0.407952 │ 0.407952 │ 0.406015 │ 0.406015 │ 4.39712e7 │ │ 3 │ 0.378004 │ 0.378004 │ 0.376216 │ 0.376216 │ 2.6432e7 │ │ 4 │ 0.385453 │ 0.38739 │ 0.385453 │ 0.385453 │ 2.16104e7 │ │ 5 │ 0.396777 │ 0.398565 │ 0.396777 │ 0.396777 │ 1.83624e7 │ │ 6 │ 0.420914 │ 0.422851 │ 0.420914 │ 0.420914 │ 1.21576e7 │ |
感谢@Matt B.提出的简化代码的建议。
上面的问题是数据框内的列类型是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # first, guess the Julia equivalent of type of the object function guess_type(x::PyCall.PyObject) string_dtype = x[:dtype][:name] julia_string = string(uppercase(string_dtype[1]), string_dtype[2:end]) return eval(parse("$julia_string")) end # convert an individual column, falling back to Any array if the guess was wrong function convert_column(x) y = try Array{guess_type(x)}(x) catch Array(x) end return y end # put everything together into a single function function convert_pandas(df) colnames = map(Symbol, data[:columns]) y = DataFrame(Any[convert_column(df[c]) for c in colnames], colnames) return y end |
上面的内容,当应用于
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | y = convert_pandas(data); showcols(y) 9147×12 DataFrames.DataFrame │ Col # │ Name │ Eltype │ Missing │ ├───────┼─────────────┼─────────┼─────────┤ │ 1 │ Open │ Float64 │ 0 │ │ 2 │ High │ Float64 │ 0 │ │ 3 │ Low │ Float64 │ 0 │ │ 4 │ Close │ Float64 │ 0 │ │ 5 │ Volume │ Float64 │ 0 │ │ 6 │ Ex-Dividend │ Float64 │ 0 │ │ 7 │ Split Ratio │ Float64 │ 0 │ │ 8 │ Adj. Open │ Float64 │ 0 │ │ 9 │ Adj. High │ Float64 │ 0 │ │ 10 │ Adj. Low │ Float64 │ 0 │ │ 11 │ Adj. Close │ Float64 │ 0 │ │ 12 │ Adj. Volume │ Float64 │ 0 │ |
你在Python / Pandas版本中遇到了差异。我碰巧有两种配置可供我轻松使用; Python 2中的Pandas 0.18.0和Python 3中的Pandas 0.19.1。@ niczky12提供的答案在第一个配置中运行良好,但我在第二个配置中看到了
使用字典界面:
1 2 3 | data = quandl.get("WIKI/AAPL", returns ="pandas") cols = keys(data) df = DataFrame(Any[collect(values(data[c])) for c in cols], map(Symbol, cols)) |
显式禁用自动转换并使用PyCall接口提取列,如另一个答案中所示的niczky12。请注意,
1 2 3 | data = pycall(quandl.get, PyObject,"WIKI/AAPL", returns ="pandas") cols = data[:columns] df = DataFrame(Any[Array(data[c]) for c in cols], map(Symbol, cols)) |
但是,在这两种情况下,请注意最重要的日期索引不包含在结果数据框中。您几乎肯定希望将其添加为列:
1 | df[:Date] = collect(data[:index]) |
有一个API。只需使用Quandl.jl:https://github.com/milktrader/Quandl.jl
1 2 | using Quandl data = quandlget("WIKI/AAPL") |
这具有以有用的Julia格式(TimeArray)获取数据的附加优点,该格式具有为处理这些数据而定义的适当方法。