title: Apply function to pandas dataframe to scan a list in a column/cell depending on an other column/cell
body: <p>I am faced with a problem while scanning rows from a <code>pandas</code> data frame. I have some input data in a data frame that are fix (columns are <code>Time</code>, <code>ID</code> and <code>frames</code>). Now I try to get some results from it. With every timestamp I get one or more LIN ID's and with every LIN ID I get one LIN frame with 8 data bytes as string. This data string represents the raw values from some sensors. </p>
  
  <p>Now I want to scan each row find the LIN ID and its corresponding LIN frame, calculate the raw sensor value and store this value in the <code>pandas</code> dataframe as new column. My problem is that I get a list of IDs and a list of LIN Frames in each row. My question is: How can I get the correct values out of these list in a cell? Is it possible with <code>apply</code> or is there an easier way?</p>
  
  <p>I hope I described it good enough, cause I'm new to this forum and a <code>python</code> beginner. Could someone take a look at the following source code and show me the right way? </p>
  
  <p>Here is a picture of the expected output: <a href="https://imgur.com/JhLJQZW" rel="nofollow noreferrer">https://imgur.com/JhLJQZW</a></p>
  
  <pre><code>from binascii import unhexlify
  
  import numpy as np
  import pandas as pd
  import sys
  
  
  def getVal(data, btn):
      '''
      Calculate 2-byte hex data to float value LSB first
      '''
      try:
          mydata = bytearray(unhexlify(data))
          b = (btn - 1) * 2
  
          # swap byteorder
          val = (mydata[b + 1] &lt;&lt; 8) + mydata[b]
  
      except:
          val = np.nan
  
      return val
  
  
  if __name__ == '__main__':
  
      # I get data in this form
      # 'Time':    one set of data every 7ms
      # 'ID':      list of LIN Ids at each timestamp
      # 'frames' : list of frames at each timestamp
  
      #=======================================================================
      # This has the correct input data, but did not works
      #=======================================================================
      df1 = pd.DataFrame(data={'Time': [0, 0.007, 0.014, 0.021, 0.028, 0.035, 0.042, 0.049, 0.056, 0.063],
                          'ID': [['11', '12', '14'], ['12'], ['13'], ['14'], [], [], ['11'], ['12'], ['13'], ['14']],
                          'frames': [['25186617A819AB19', 'B31A031A5F1ADF1A', 'AD18D517DD150000'], ['07D06617a719ab19'], ['0BB86617a719ab19'], ['0FA06617a719ab19'], [], [], ['33186617a719ab19'], ['33186617a719ab19'], ['33186617a719ab19'], ['33186617a719ab19']]})
  
      # build names Btn_0_raw up to Btn_15_raw as column names
      names = ["Btn_{}_raw".format(x) for x in range(16)]
  
      # LIN IDs to search for
      linIDs = ['11', '12', '13', '14']
  
      # show values to check they are correct
  #     print names
  #     print df1["Time"].head()
  #     print df1.iloc[:]
  #     print df1["frames"].head()
  #              
  
      error = False
  
      # #loop over 16 buttons
      for btn in range(16):  
  
          # show that all variables are correct; 
          # use constant hex data for each button group of 4 button; 
          # values are (100,200,300,400) (0x0064,0x00c8,0x012c,0x0190)
          print "{0}:{1}, ID({2}), bytePos({3}), demo value:{4}".format(btn, names[btn], linIDs[btn / 4], (btn % 4) + 1, getVal('6400C8002c019001', (btn % 4) + 1)) 
  
          try:
              df1[names[btn]] = df1['frames'].where(linIDs[btn / 4] in df1['ID'], np.nan).apply(lambda x: getVal(x, (btn % 4) + 1))
          except ValueError as e:
              print " Value error :", e
              error = True
  
      if not error:
          df1.to_excel('test-1.xls')
  
  
  
      #===========================================================================
      # An example that works, but unfortunately this input data are incorrect
      #===========================================================================
      df2 = pd.DataFrame(data={'Time': [0, 0.007, 0.014, 0.021, 0.028, 0.035, 0.042, 0.049, 0.056, 0.063],
                              'ID': ['11', '12', '13', '14', np.nan, np.nan, '11', '12', '13', '14'],
                              'frames': ['6400C8002c019001', '6500C9002d019101', '6600CA002e019201', '6700CB002F019301', '', '', '6400C8002c019001', '6500C9002d019101', '6600CA002e019201', '6700CB002F019301']
                              })
  
      error = False
  
      # loop over 16 buttons
      for btn in range(16):  
  
          # show that all variables are correct; 
          print "{0}:{1}, ID({2}), bytePos({3}), demo value:{4}".format(btn, names[btn], linIDs[btn / 4], (btn % 4) + 1, getVal('6400C8002c019001', (btn % 4) + 1)) 
  
          try:
              df2[names[btn]] = df2['frames'].where(df2['ID'] == linIDs[btn / 4] , np.nan).apply(lambda x: getVal(x, (btn % 4) + 1))
              print df2[names[btn]]
          except ValueError as e:
              print " Value error :", e
              error = True
  
      if not error:
          df2.to_excel("test-2.xls")
  </code></pre>