Feature request: Delete element/vector/plane/etc #5

Closed
dicom opened this Issue Feb 17, 2011 · 5 comments

Projects

None yet

2 participants

@dicom
dicom commented Feb 17, 2011

Thanks for the work you do with this very useful Ruby gem!

Recently I came across the need to delete specific rows/columns or planes from my NArrays. I have searched the documentation, but couldnt find a method for this. Please excuse me if I have missed it. I wonder if you think a method like this would be useful for NArray?

Example of what I would like:
self.delete(dim, index_or_indices)

# Delete column 1 from a two-dimensional array:
a = NArray.int(2,3).indgen!
[ [ 0, 1 ],
  [ 2, 3 ],
  [ 4, 5 ] ]
a.delete(0, 1)
[ [ 0 ],
  [ 2 ],
  [ 4 ] ]

# Delete rows 1 and 3 from a two-dimensional array:
b = NArray.int(2,4).indgen!
[ [ 0, 1 ],
  [ 2, 3 ],
  [ 4, 5 ],
  [ 6, 7 ] ]
b.delete(1, [1,3])
[ [ 0, 1 ],
  [ 4, 5 ] ]

# Delete a plane from a three-dimensional array:
c = NArray.int(2,2,3).indgen!
[ [ [ 0, 1 ],
    [ 2, 3 ] ],
  [ [ 4, 5 ],
    [ 6, 7 ] ],
  [ [ 8, 9 ],
    [ 10, 11 ] ] ]
c.delete(2, 2)
[ [ [ 0, 1 ],
    [ 2, 3 ] ],
  [ [ 4, 5 ],
    [ 6, 7 ] ] ]

I am aware that it is possible to extract specific elements/vectors/planes/etc from an NArray, but in some cases it is easier and more desireable to be able to remove specific indices from your array, rather than extract the others.

Best regards,
Chris

@masa16
Owner
masa16 commented Feb 18, 2011

New method is added:
irb(main):001:0> NArray.float(4,3).indgen.delete(0)
=> NArray.float(3,3):
[ [ 1.0, 2.0, 3.0 ],
[ 5.0, 6.0, 7.0 ],
[ 9.0, 10.0, 11.0 ] ]
irb(main):002:0> NArray.float(4,3).indgen.delete(-1)
=> NArray.float(3,3):
[ [ 0.0, 1.0, 2.0 ],
[ 4.0, 5.0, 6.0 ],
[ 8.0, 9.0, 10.0 ] ]
irb(main):003:0> NArray.float(4,3).indgen.delete(nil,1)
=> NArray.float(4,2):
[ [ 0.0, 1.0, 2.0, 3.0 ],
[ 8.0, 9.0, 10.0, 11.0 ] ]
irb(main):004:0> NArray.float(4,3).indgen.delete([0,2])
=> NArray.float(2,3):
[ [ 1.0, 3.0 ],
[ 5.0, 7.0 ],
[ 9.0, 11.0 ] ]
irb(main):006:0> NArray.float(4,3).indgen.delete(nil, 1..-1)
=> NArray.float(4,1):
[ [ 0.0, 1.0, 2.0, 3.0 ] ]
irb(main):001:0> NArray.float(4,3).indgen.delete(1..-2, 1..-2)
=> NArray.float(2,2):
[ [ 0.0, 3.0 ],
[ 8.0, 11.0 ] ]

code:
class NArray
# delete rows/columns
def delete(_args)
if args.size > self.rank
raise ArgumentError, "too many arguments"
end
shp = self.shape
ind = []
self.rank.times do |i|
n = shp[i]
case a=args[i]
when Integer
a = n+a if a<0
raise IndexError, "index(%d) out of range"%[a] if a<0
x = [0...a,a+1...n]
when Range
b = a.first
b = n+b if b<0
raise IndexError, "index(%s) out of range"%[a] if b<0
e = a.last
e = n+e if e<0
e -= 1 if a.exclude_end?
raise IndexError, "index(%s) out of range"%[a] if e<0
x = [0...b,e+1...n]
when Array
x = (0...n).to_a
x -= a
else
if a
raise ArgumentError, "invalid argument"
else
x = true
end
end
ind << x
end
self[_ind]
end
end

Thank you for your comment.

@masa16
Owner
masa16 commented Feb 18, 2011

I think the method name "delete" is too general and does not explain the operation.
Any good name?

@dicom
dicom commented Feb 18, 2011

Thank you Masahiro for your quick feedback!

I like your syntax. It is better than my suggestion.

I agree that delete is slightly general and may not accurately describe the behaviour of the method.

Another thing to consider is if it is more natural to have an ! in this method name, since it modifies self?

A good alternative is delete_at() [or delete_at!()], which is the method name used for Ruby Array. I think this method name is more descriptive, although it is slightly longer.

Some other possible options:
remove() or remove_at()
extract() or extract_at()
cut() or cut_at()
eliminate() or eliminate_at()
detach() or detach_at()
amputate() amputate_at()
strip() or strip_at()
scrub() or scrub_at()
scrap() or scrap_at()
erase() or erase_at()
expunge() or expunge_at()
withdraw() or withdraw_at()

@masa16
Owner
masa16 commented Feb 18, 2011

delete_at seems to be the best. Thanks.

This method does not modify self. It returns a copy.
It should not have ! in the name.

@dicom
dicom commented Sep 13, 2011

This issue was really solved a long time ago, and recently it was finally released in a gem, so I thought I'd go ahead and close this issue.

However, there is one small request I would like to make:
Could you add this method to the NArray documentation?
It is currently missing, at http://narray.rubyforge.org/SPEC.en.

Thanks.

@dicom dicom closed this Sep 14, 2011
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment