4
$\begingroup$

I would like to use the Feature Constructor to extract numbers from a column of strings.

 Input          Output
S.c 3224   ---> 3224
South      ---> 0
322523     ---> 322523
S-1c 4     ---> 14
-1.37      ---> 137

Internal Orange 3.7.0 Documentation says For continuous variables you only have to construct an expression in Python. Great!

I found information about allowed functions in the feature constructor code:

#Only expressions with no list,set,dict,generator comprehensions
#are accepted.
<...>
__ALLOWED = [
    "Ellipsis", "False", "None", "True", "abs", "all", "any", "acsii",
    "bin", "bool", "bytearray", "bytes", "chr", "complex", "dict",
    "divmod", "enumerate", "filter", "float", "format", "frozenset",
    "getattr", "hasattr", "hash", "hex", "id", "int", "iter", "len",
    "list", "map", "memoryview", "next", "object",
    "oct", "ord", "pow", "range", "repr", "reversed", "round",
    "set", "slice", "sorted", "str", "tuple", "type",
    "zip"
]

Based on the list, I was hoping to use an expression like this:
int(filter(str.isdigit, inputStringColumn) or 0)

...but that is an "Invalid Expression" (no further feedback)

How can I extract a number from a string?

$\endgroup$
5
  • 1
    $\begingroup$ How about int(inputStringColumn) if inputStringColumn.isdigit() else 0 ? $\endgroup$
    – Stephen Rauch
    Nov 15, 2017 at 20:40
  • $\begingroup$ @StephenRauch "Attribute Error: 'Value' object has no attribute 'isdigit'" $\endgroup$
    – Adam
    Nov 15, 2017 at 20:45
  • $\begingroup$ @StephenRauch Part of the trouble - I thought the column was a string because it has letters, but it isn't. If I first cast to string, then your solution at least runs . int(str(inputStringColumn)) if str(inputStringColumn).isdigit() else 0 It doesn't work completely, however - when the whole field is digits, it returns those digits. Otherwise it returns 0 (it isn't going piecewise through.) $\endgroup$
    – Adam
    Nov 15, 2017 at 20:49
  • 3
    $\begingroup$ With help from the error message generated by Stephen Rauch's suggestion, I worked out one way to do this: int( ''.join(filter(str.isdigit, "0"+str(inputColumn) ) )) I will write this up as an answer later, unless someone comes along with something better. $\endgroup$
    – Adam
    Nov 15, 2017 at 21:00
  • 1
    $\begingroup$ It would be much nicer if re (regex) module were exposed. While writing up the answer, also consider opening a bug/enhancement report. :D $\endgroup$
    – K3---rnc
    Nov 16, 2017 at 12:48

1 Answer 1

1
$\begingroup$

Just to highlight Adam's timesaving answer

int(''.join(filter(str.isdigit, "0"+str(inputColumn))))

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.