3

I tried the link. But it doesnt work for my example given below. I tried the loc[0] for the output. I tried .item(). But none of these help me.

>>> df2 = pd.DataFrame({ 'Item':['[Phone]', '[Watch]', '[Pen]', '[Pencil]', '[Knife]'], 'RelatedItem': ['[Phone cover]', '[Watch strap]', '[Pen cap]', '[Pencil lead]', '[fork]'], 'CountinInventory':['20','50','40','80','90']})
>>> df2
    Item     RelatedItem   CountinInventory
0   [Phone]  [Phone cover]               20
1   [Watch]  [Watch strap]               50
2     [Pen]      [Pen cap]               40
3  [Pencil]  [Pencil lead]               80
4   [Knife]         [fork]               90
>>> df2.loc[df2['Item'] == 'Phone', 'RelatedItem']
Series([], Name: RelatedItem, dtype: object)
>>> df2.loc[df2['Item'] == 'Phone', 'RelatedItem', 'CountinInventory']
pandas.core.indexing.IndexingError: Too many indexers

I have this data where when I feed Phone, I need to get Phone cover along with the CountinInventory value as my answer. Please advice what mistake am I doing here.

Zoe
  • 27,060
  • 21
  • 118
  • 148
Sudhi
  • 421
  • 1
  • 8
  • 19

2 Answers2

3

I believe you need str for remove first and last [] or use str.strip:

mask = df2['Item'].str[1:-1] == 'Phone'
#alternative solution
#mask = df2['Item'].str.strip('[]') == 'Phone'

print (mask)
0     True
1    False
2    False
3    False
4    False
Name: Item, dtype: bool

If no missing values is possible use list comprehension, what is faster if large data:

mask = [x[1:-1] == 'Phone'for x in df2['Item']]

mask = [x.strip('[]') == 'Phone'for x in df2['Item']]
print (mask)

[True, False, False, False, False]

Last for select multiple columns use list:

df3 = df2.loc[mask, ['RelatedItem', 'CountinInventory']]
print (df3)
     RelatedItem CountinInventory
0  [Phone cover]               20
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252
  • Thank you for the answer. But if I a webpage will send in an api request with the Item name and I need to return the 'RelatedItem' and 'CountinInventory' then the mask based option wouldn't be a good one right? I am curious. Do you think just returning the output values like 'Phone cover' and '20' alone is possible – Sudhi Oct 10 '18 at 12:43
  • @Sudhi - Do you think `print (df3.to_string(index=False, header=None))` ? – jezrael Oct 10 '18 at 12:45
  • 1
    Cool this seems to return only the necessary output values. perfect. Thank you very much! – Sudhi Oct 10 '18 at 12:48
  • @Sudhi - And also if want return first matched value `print (next(iter(df3['RelatedItem']), 'no match')) print (next(iter(df3['CountinInventory']), 'no match'))` – jezrael Oct 10 '18 at 12:49
  • Would you mind if I ask you one question? I am trying to get a user input like `name = input('Write Item Name of your choice -')`. But I am unable to pass the input as string inside `next(iter(df3[name]), 'no match'))` to get the other to column values that I am interested in. Any suggestions – Sudhi Oct 11 '18 at 15:53
  • @Sudhi It should working nice, if use `name = 'Item'` it nor working? Now I am offline, on phone only, so cannot tested. – jezrael Oct 11 '18 at 16:03
  • no worries. Thanks for responding. I shall try to figure out myself. Else will ask new question – Sudhi Oct 11 '18 at 16:18
  • what was problem? – jezrael Oct 11 '18 at 17:39
  • 1
    I made mistake in the way the string input was being used. I had to add single quotes before I passed into the script to get the other columns I needed. – Sudhi Oct 11 '18 at 17:48
1

You could also use:

df.loc[df['Item'].str.contains('Phone'), ['RelatedItem',  'CountinInventory']]

The error too many indexers is because df.loc[] expects an array of labels, list or slice object with labels. But you have given a sequence of 'labels'.

Mohit Motwani
  • 4,662
  • 3
  • 17
  • 45