Reputation: 387
I produce a number of large arrays in Julia using a script file. Printing out the whole array is cumbersome but I'd like to check the first few rows make sense.
I know in the REPL there's printing which is limited by the screen size e.g.
julia> zeros(1000,10)
1000×10 Array{Float64,2}:
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
⋮ ⋮
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
But I can't find any print/show function in base Julia which mimics this for scripts, say only printing out the first 10 rows of an array or something like R's head
(I would have expected showcompact
to do something like this).
Is there an analogous function to R's head
in Julia or do I have to write my own.
Upvotes: 14
Views: 6756
Reputation: 12051
As I mentioned in a comment, the way to do this in v0.5 is to use an IOContext
.
A very simple way to limit the data is to pass the :limit => true
parameter to the IOContext
;
julia> show(IOContext(stdout, :limit => true), v)
[0.147959 0.414018 … 0.595528 0.852563; 0.32679 0.824953 … 0.432143 0.036279; … ; 0.877398 0.661854 … 0.197207 0.15596; 0.0522946 0.508075 … 0.835359 0.705987]
But this still does not print out the way the REPL does; that's because show
with two arguments uses a single-line display. To use a multiline display, pass text/plain
as the second argument to show
(a MIME type):
julia> show(IOContext(stdout, :limit => true), "text/plain", v)
100×100 Array{Float64,2}:
0.147959 0.414018 0.0282934 … 0.816132 0.595528 0.852563
0.32679 0.824953 0.0582351 0.822526 0.432143 0.036279
0.754989 0.724317 0.533966 0.987273 0.931932 0.973622
0.547866 0.282694 0.0295411 0.75929 0.886218 0.0813057
0.0626663 0.111795 0.625083 0.439983 0.562143 0.669046
0.712093 0.469622 0.377298 … 0.298224 0.31853 0.376066
0.774625 0.754328 0.756725 0.61113 0.76566 0.999292
0.917846 0.308363 0.489246 0.715311 0.175302 0.124059
0.310922 0.140575 0.20635 0.0280192 0.683004 0.168129
0.753361 0.755103 0.831806 0.118009 0.122374 0.281476
⋮ ⋱
0.420264 0.7614 0.748408 0.330983 0.0776789 0.309464
0.984379 0.851735 0.595121 0.534982 0.255317 0.743713
0.814505 0.765941 0.71852 0.730677 0.477631 0.0360992
0.910384 0.0747604 0.490685 0.0904559 0.0756424 0.313898
0.628416 0.0790874 0.401488 … 0.523521 0.397249 0.58112
0.578361 0.336352 0.261118 0.838256 0.387374 0.451647
0.66724 0.586342 0.378968 0.602694 0.450686 0.901279
0.877398 0.661854 0.685156 0.658952 0.197207 0.15596
0.0522946 0.508075 0.244423 0.95935 0.835359 0.705987
You can of course change how many rows are shown by passing in :displaysize
to the IOContext
:
julia> show(IOContext(stdout, :limit => true, :displaysize => (10, 10)), "text/plain", v)
100×100 Array{Float64,2}:
0.147959 … 0.852563
0.32679 0.036279
0.754989 0.973622
⋮ ⋱
0.877398 0.15596
0.0522946 0.705987
Overall, IOContext
is very flexible. See its documentation for more details.
Upvotes: 22
Reputation: 21
I believe this thread is out of date. For me on julia v1.4.1 , the display function does not print a limited array, and
a = zeros(1000,6)
show(IOContext(STDOUT, limit=true), "text/plain", a)
yields an error. Instead I found this works
a = zeros(1000,6)
show(IOContext(stdout, :limit => true), "text/plain", a)
Upvotes: 2
Reputation: 7395
We can get the same output as REPL by using display()
(is this what you are looking for...?) Also, the "head" and "tail" parts can be printed by using array sections, e.g.,
disp( x ) = ( display(x) ; println() ; println() )
A = diagm( [ i for i=1:100 ] )
disp( A )
disp( A[ 1:5, : ] ) # head
disp( A[ end-4:end, : ] ) # tail
B = [ i for i=1:100 ]
disp( B )
disp( B[ 1:5 ] ) # head
disp( B[ end-4:end ] ) # tail
$ julia test.jl
100x100 Array{Int64,2}:
1 0 0 0 0 0 0 0 0 0 0 0 … 0 0 0 0 0 0 0 0 0
0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 6 0 0 0 0 0 0 … 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 8 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 9 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0
⋮ ⋮ ⋮ ⋱ ⋮
0 0 0 0 0 0 0 0 0 0 0 0 92 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 93 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 94 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 95 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 … 0 0 0 0 96 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 97 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 98 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 99 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 100
5x100 Array{Int64,2}:
1 0 0 0 0 0 0 0 0 0 0 0 0 … 0 0 0 0 0 0 0 0 0 0 0 0
0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5x100 Array{Int64,2}:
0 0 0 0 0 0 0 0 0 0 0 0 0 … 0 0 0 0 0 96 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 97 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 98 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 99 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 100
100-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
10
⋮
92
93
94
95
96
97
98
99
100
5-element Array{Int64,1}:
1
2
3
4
5
5-element Array{Int64,1}:
96
97
98
99
100
Upvotes: 4
Reputation: 2096
You could easily define a head
function yourself. For one and two dimensions, this is pretty straightforward:
torange(n::Integer, m) = 1:min(n, m)
torange(c::Colon, m) = (:)
function head(a::AbstractArray{TypeVar(:T), 1}, n = 10)
view(a, torange(n,size(a,1)))
end
function head(a::AbstractArray{TypeVar(:T), 2}, n1 = 10, n2 = 10)
view(a, torange(n1, size(a,1)), torange(n2, size(a,2)))
end
The torange
method allows to use a :
to return the full length in the corresponding dimension. For example
head(zeros(10, 10), 5, :)
5×10 SubArray{Float64,2,Array{Float64,2},Tuple{UnitRange{Int64},Colon},false}:
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
For more than two dimensions, I have chosen to repeat the last argument beginning from the third:
function head{Na, Nn}(a::AbstractArray{TypeVar(:T), Na}, n1 = 10, n2 = 10, ns::Vararg{TypeVar(:T), Nn} = 2)
nend = last(ns)
view(a, torange(n1, size(a,1)), torange(n2, size(a,2)), (torange(ns[i], size(a,i+2)) for i = 1:Nn)..., (torange(nend, size(a, i)) for i in Nn+3:Na)...)
end
For example:
head(rand(10, 10, 5, 5), 3, 3, 2) # the last two is the default value and can be omitted
3×3×2×2 SubArray{Float64,4,Array{Float64,4},Tuple{UnitRange{Int64},UnitRange{Int64},UnitRange{Int64},UnitRange{Int64}},false}:
[:, :, 1, 1] =
0.384724 0.7328 0.585211
0.738284 0.95145 0.362914
0.43928 0.94307 0.758541
[:, :, 2, 1] =
0.78603 0.588877 0.677201
0.559547 0.800559 0.488433
0.993593 0.691884 0.236595
[:, :, 1, 2] =
0.25732 0.90491 0.323905
0.300924 0.703919 0.813316
0.040522 0.776142 0.624097
[:, :, 2, 2] =
0.746677 0.153574 0.155539
0.991624 0.90167 0.0880094
0.0423263 0.0153597 0.0608328
Note that the n-dimensional version is not type-stable, but that shouldn't matter for printing.
Upvotes: 4