3
$\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$
  • 1
    $\begingroup$ How about int(inputStringColumn) if inputStringColumn.isdigit() else 0 ? $\endgroup$ – Stephen Rauch Nov 15 '17 at 20:40
  • $\begingroup$ @StephenRauch "Attribute Error: 'Value' object has no attribute 'isdigit'" $\endgroup$ – Adam Nov 15 '17 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 '17 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 '17 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 '17 at 12:48
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, privacy policy and cookie policy

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